Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Pouyollon2015-05-04 14:42:37 +0000
committerXavier Pouyollon2015-05-05 09:00:18 +0000
commita11ae4d89c7899ba975b9f924f340515c21ce28a (patch)
treeb07f5685077b21bda96494f8cf06314031d1289a
parenteafe5eaa4e338d2eaa3e81b4eb0164f9b8013ddc (diff)
downloadorg.eclipse.tcf.agent-a11ae4d89c7899ba975b9f924f340515c21ce28a.tar.gz
org.eclipse.tcf.agent-a11ae4d89c7899ba975b9f924f340515c21ce28a.tar.xz
org.eclipse.tcf.agent-a11ae4d89c7899ba975b9f924f340515c21ce28a.zip
PPC64 breakpoint support.
Support LocalEntryPoint for PPC64. Signed-off-by: Xavier Pouyollon <xavier.pouyollon@windriver.com>
-rw-r--r--agent/tcf/services/breakpoints.c17
-rw-r--r--agent/tcf/services/symbols.c7
-rw-r--r--agent/tcf/services/symbols.h3
-rw-r--r--agent/tcf/services/symbols_elf.c24
-rw-r--r--agent/tcf/services/symbols_proxy.c1
-rw-r--r--agent/tcf/services/tcf_elf.c4
-rw-r--r--agent/tcf/services/tcf_elf.h1
7 files changed, 54 insertions, 3 deletions
diff --git a/agent/tcf/services/breakpoints.c b/agent/tcf/services/breakpoints.c
index b74313c6..ed13c22e 100644
--- a/agent/tcf/services/breakpoints.c
+++ b/agent/tcf/services/breakpoints.c
@@ -1421,10 +1421,18 @@ static void plant_at_address_expression(Context * ctx, ContextAddress ip, Breakp
ContextAddress size = 1;
int error = 0;
Value v;
-
+ SymbolProperties props;
+
if (evaluate_expression(ctx, STACK_NO_FRAME, ip, bp->location, 1, &v) < 0) error = errno;
if (!error && value_to_address(&v, &addr) < 0) error = errno;
+ if (v.sym != NULL) {
+ /* We want to add the LocalEntryOffset */
+ get_symbol_props(v.sym, &props);
+ /* If the symbol is not a PPC64 function, offset should be 0, so it is safe to add */
+ addr += props.local_entry_offset;
+ }
#if ENABLE_SkipPrologueWhenPlanting
+ /* Even if addr is incremented by local_entry_offset, we still should be on right code area */
if (!error && bp->skip_prologue && v.sym != NULL && skip_function_prologue(ctx, v.sym, &addr) < 0) error = errno;
#endif
if (bp->access_size > 0) {
@@ -1456,8 +1464,13 @@ static void plant_at_address_expression(Context * ctx, ContextAddress ip, Breakp
unsigned n = 0;
while (v.sym_list[n] != NULL) {
Symbol * sym = v.sym_list[n++];
- if (get_symbol_address(sym, &addr) == 0) {
+ if (get_symbol_address(sym, &addr) == 0) {
+ /* We want to add the LocalEntryOffset */
+ get_symbol_props(sym, &props);
+ /* If the symbol is not a PPC64 function, offset should be 0, so it is safe to add */
+ addr += props.local_entry_offset;
#if ENABLE_SkipPrologueWhenPlanting
+ /* Even if addr is incremented by local_entry_offset, we still should be on right code area */
if (bp->skip_prologue) skip_function_prologue(ctx, sym, &addr);
#endif
plant_breakpoint(ctx, bp, addr, size);
diff --git a/agent/tcf/services/symbols.c b/agent/tcf/services/symbols.c
index d146d7cb..edbf834f 100644
--- a/agent/tcf/services/symbols.c
+++ b/agent/tcf/services/symbols.c
@@ -303,6 +303,13 @@ static void command_get_context_cache_client(void * x) {
write_stream(&c->out, ',');
}
+ if (props.local_entry_offset != 0) {
+ json_write_string(&c->out, "LocalEntryOffset");
+ write_stream(&c->out, ':');
+ json_write_ulong(&c->out, props.local_entry_offset);
+ write_stream(&c->out, ',');
+ }
+
if (value != NULL) {
json_write_string(&c->out, "Value");
write_stream(&c->out, ':');
diff --git a/agent/tcf/services/symbols.h b/agent/tcf/services/symbols.h
index 143e9ac5..33a39972 100644
--- a/agent/tcf/services/symbols.h
+++ b/agent/tcf/services/symbols.h
@@ -91,7 +91,8 @@ typedef uint32_t SYM_FLAGS;
typedef struct SymbolProperties {
int binary_scale; /* The exponent of the base two scale factor to be applied to an instance of the type */
int decimal_scale; /* The exponent of the base ten scale factor to be applied to an instance of the type */
- unsigned bit_stride;
+ unsigned bit_stride;
+ unsigned int local_entry_offset; /* Only PPC64 v2 supports it */
} SymbolProperties;
/* Symbol properties update policies */
diff --git a/agent/tcf/services/symbols_elf.c b/agent/tcf/services/symbols_elf.c
index a38655e6..c014961d 100644
--- a/agent/tcf/services/symbols_elf.c
+++ b/agent/tcf/services/symbols_elf.c
@@ -4147,6 +4147,11 @@ int get_symbol_flags(const Symbol * sym, SYM_FLAGS * flags) {
}
int get_symbol_props(const Symbol * sym, SymbolProperties * props) {
+#define STO_PPC64_LOCAL_BIT 5
+#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
+#define IS_PPC64_V2(elfsym) ((elfsym->file->machine == EM_PPC64) && (elfsym->file->flags & 0x3) == 2)
+
+ ELF_SymbolInfo elf_sym_info;
ObjectInfo * obj = sym->obj;
assert(sym->magic == SYMBOL_MAGIC);
memset(props, 0, sizeof(SymbolProperties));
@@ -4162,6 +4167,25 @@ int get_symbol_props(const Symbol * sym, SymbolProperties * props) {
if (get_num_prop(obj, AT_stride_size, &n)) props->bit_stride = (unsigned)n;
}
}
+
+ /* PowerPC64 ABIv2 computes local offset from st_other */
+ if (sym->tbl != NULL) {
+ /* Only do that on PPC64 v2 */
+ if (!IS_PPC64_V2(sym->tbl))
+ return 0;
+ unpack_elf_symbol_info(sym->tbl, sym->index, &elf_sym_info);
+ } else {
+ Symbol *elf_symbol;
+ /* From Dwarf object to Elf symbol */
+ map_to_sym_table(sym->obj, &elf_symbol);
+ if (elf_symbol == NULL)
+ return 0;
+ if (!IS_PPC64_V2(elf_symbol->tbl))
+ return 0;
+ unpack_elf_symbol_info(elf_symbol->tbl, elf_symbol->index, &elf_sym_info);
+ }
+ /* We can compute the offset now */
+ props->local_entry_offset = (((1 << (((elf_sym_info.other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2);
return 0;
}
diff --git a/agent/tcf/services/symbols_proxy.c b/agent/tcf/services/symbols_proxy.c
index bc398e80..22e6bdd8 100644
--- a/agent/tcf/services/symbols_proxy.c
+++ b/agent/tcf/services/symbols_proxy.c
@@ -671,6 +671,7 @@ static void read_context_data(InputStream * inp, const char * name, void * args)
else if (strcmp(name, "BinaryScale") == 0) s->props.binary_scale = (int)json_read_long(inp);
else if (strcmp(name, "DecimalScale") == 0) s->props.decimal_scale = (int)json_read_long(inp);
else if (strcmp(name, "BitStride") == 0) s->props.bit_stride = (unsigned)json_read_ulong(inp);
+ else if (strcmp(name, "LocalEntryOffset") == 0) s->props.local_entry_offset = (unsigned)json_read_ulong(inp);
else if (strcmp(name, "Flags") == 0) s->flags = json_read_ulong(inp);
else if (strcmp(name, "Frame") == 0) s->frame = (int)json_read_long(inp);
else json_skip_object(inp);
diff --git a/agent/tcf/services/tcf_elf.c b/agent/tcf/services/tcf_elf.c
index 481188c0..a10f2c5c 100644
--- a/agent/tcf/services/tcf_elf.c
+++ b/agent/tcf/services/tcf_elf.c
@@ -1679,6 +1679,7 @@ void unpack_elf_symbol_info(ELF_Section * sym_sec, U4_T index, ELF_SymbolInfo *
SWAP(s.st_shndx);
SWAP(s.st_size);
SWAP(s.st_value);
+ SWAP(s.st_other);
}
st_name = (size_t)s.st_name;
info->section_index = s.st_shndx;
@@ -1686,6 +1687,7 @@ void unpack_elf_symbol_info(ELF_Section * sym_sec, U4_T index, ELF_SymbolInfo *
info->type = ELF64_ST_TYPE(s.st_info);
info->value = s.st_value;
info->size = s.st_size;
+ info->other = s.st_other;
}
else {
Elf32_Sym s = *(Elf32_Sym *)((U1_T *)sym_sec->data + sym_sec->entsize * index);
@@ -1694,6 +1696,7 @@ void unpack_elf_symbol_info(ELF_Section * sym_sec, U4_T index, ELF_SymbolInfo *
SWAP(s.st_shndx);
SWAP(s.st_size);
SWAP(s.st_value);
+ SWAP(s.st_other);
}
st_name = (size_t)s.st_name;
info->section_index = s.st_shndx;
@@ -1701,6 +1704,7 @@ void unpack_elf_symbol_info(ELF_Section * sym_sec, U4_T index, ELF_SymbolInfo *
info->type = ELF32_ST_TYPE(s.st_info);
info->value = s.st_value;
info->size = s.st_size;
+ info->other = s.st_other;
}
if (info->section_index > 0 && info->section_index < file->section_cnt) {
diff --git a/agent/tcf/services/tcf_elf.h b/agent/tcf/services/tcf_elf.h
index a1129aed..8fe8997b 100644
--- a/agent/tcf/services/tcf_elf.h
+++ b/agent/tcf/services/tcf_elf.h
@@ -477,6 +477,7 @@ struct ELF_SymbolInfo {
U1_T type;
U8_T value;
U8_T size;
+ U8_T other;
};
struct ELF_Section {

Back to the top