File: reloc.c

package info (click to toggle)
libi8x 0.0.5-1
  • links: PTS
  • area: main
  • in suites: sid
  • size: 7,192 kB
  • ctags: 1,365
  • sloc: ansic: 6,874; python: 1,339; makefile: 146; sh: 102
file content (113 lines) | stat: -rw-r--r-- 2,967 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* Copyright (C) 2016-17 Red Hat, Inc.
   This file is part of the Infinity Note Execution Library.

   The Infinity Note Execution Library is free software; you can
   redistribute it and/or modify it under the terms of the GNU Lesser
   General Public License as published by the Free Software
   Foundation; either version 2.1 of the License, or (at your option)
   any later version.

   The Infinity Note Execution Library is distributed in the hope that
   it will be useful, but WITHOUT ANY WARRANTY; without even the
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
   PURPOSE.  See the GNU Lesser General Public License for more
   details.

   You should have received a copy of the GNU Lesser General Public
   License along with the Infinity Note Execution Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <string.h>
#include "libi8x-private.h"
#include "reloc-private.h"

void
i8x_reloc_invalidate_for_inferior (struct i8x_reloc *reloc,
				   struct i8x_inf *inf)
{
  if (reloc->cached_from != inf)
    return;

  /* Set cached_from to something that definitely isn't an
     inferior, and poison the cached value too while we're
     at it.  */
  reloc->cached_from = (struct i8x_inf *) reloc;
  reloc->cached_value = I8X_POISON_BAD_CACHED_RELOC;

  dbg (i8x_reloc_get_ctx (reloc),
       "invalidated reloc %p value for inferior %p\n", reloc, inf);
}

static i8x_err_e
i8x_reloc_init (struct i8x_reloc *reloc, ssize_t srcoffset,
		uintptr_t unrelocated)
{
  reloc->srcoffset = srcoffset;
  reloc->unrelocated = unrelocated;

  i8x_reloc_invalidate_for_inferior (reloc, reloc->cached_from);
  i8x_assert (reloc->cached_from == (struct i8x_inf *) reloc);

  return I8X_OK;
}

const struct i8x_object_ops i8x_reloc_ops =
  {
    "reloc",			/* Object name.  */
    sizeof (struct i8x_reloc),	/* Object size.  */
    NULL,			/* Unlink function.  */
    NULL,			/* Free function.  */
  };

i8x_err_e
i8x_reloc_new (struct i8x_code *code, ssize_t srcoffset,
	       uintptr_t unrelocated, struct i8x_reloc **reloc)
{
  struct i8x_reloc *r;
  i8x_err_e err;

  err = i8x_ob_new (code, &i8x_reloc_ops, &r);
  if (err != I8X_OK)
    return err;

  err = i8x_reloc_init (r, srcoffset, unrelocated);
  if (err != I8X_OK)
    {
      r = i8x_reloc_unref (r);

      return err;
    }

  dbg (i8x_code_get_ctx (code),
       "reloc %p is " LHEX "," LHEX "\n", r, srcoffset, unrelocated);

  *reloc = r;

  return I8X_OK;
}

static struct i8x_code *
i8x_reloc_get_code (struct i8x_reloc *reloc)
{
  return (struct i8x_code *)
    i8x_ob_get_parent ((struct i8x_object *) reloc);
}


I8X_EXPORT struct i8x_func *
i8x_reloc_get_func (struct i8x_reloc *reloc)
{
  return i8x_code_get_func (i8x_reloc_get_code (reloc));
}

I8X_EXPORT ssize_t
i8x_reloc_get_src_offset (struct i8x_reloc *reloc)
{
  return reloc->srcoffset;
}

I8X_EXPORT uintptr_t
i8x_reloc_get_unrelocated (struct i8x_reloc *reloc)
{
  return reloc->unrelocated;
}