summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChang S. Bae <chang.seok.bae@intel.com>2017-04-08 02:25:14 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2017-04-17 14:00:18 -0700
commit6d1459647647b3f2257e6b9a81b8eb1f6b63d946 (patch)
tree7c6eddfe259eb968561d84a53a1059470d0118e2
parent6a912a3c903db14b878a2328a86379b6a0b9266d (diff)
downloadnasm-6d1459647647b3f2257e6b9a81b8eb1f6b63d946.tar.gz
outmacho: dwarf debug (2/4)
file and section list added for managing debug line info also, now macho parts get to call debug interfaces Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--output/outmacho.c144
1 files changed, 141 insertions, 3 deletions
diff --git a/output/outmacho.c b/output/outmacho.c
index 7aa519b1..75bcedf6 100644
--- a/output/outmacho.c
+++ b/output/outmacho.c
@@ -320,6 +320,33 @@ static struct section *get_section_by_index(const int32_t index)
return s;
}
+struct file_list {
+ struct file_list *next;
+ struct file_list *last;
+ char *file_name;
+ uint32_t file;
+};
+
+struct dw_sect_list {
+ struct SAA *psaa;
+ int32_t section;
+ uint32_t line;
+ uint64_t offset;
+ uint32_t file;
+ struct dw_sect_list *next;
+ struct dw_sect_list *last;
+};
+
+struct section_info {
+ uint64_t size;
+ int32_t secto;
+};
+
+static struct file_list *dw_head_list = 0, *dw_cur_list = 0, *dw_last_list = 0;
+static struct dw_sect_list *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
+static uint32_t cur_line = 0, dw_num_files = 0, dw_num_sects = 0;
+static bool dbg_immcall = false;
+
/*
* Special section numbers which are used to define Mach-O special
* symbols, which can be used with WRT to provide PIC relocation
@@ -551,6 +578,16 @@ static void macho_output(int32_t secto, const void *data,
nasm_panic(0, "text section not found");
}
+ /* debug code generation only for sections tagged with
+ * instruction attribute */
+ if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
+ {
+ struct section_info sinfo;
+ sinfo.size = s->size;
+ sinfo.secto = secto;
+ dfmt->debug_output(0, &sinfo);
+ }
+
is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
if (is_bss && type != OUT_RESERVE) {
@@ -1594,6 +1631,8 @@ static void macho_cleanup(void)
struct reloc *r;
struct symbol *sym;
+ dfmt->cleanup();
+
/* Sort all symbols. */
macho_layout_symbols (&nsyms, &strslen);
@@ -1733,19 +1772,118 @@ static void macho_dbg_init(void)
static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
{
- (void)file_name;
- (void)line_num;
+ bool need_new_list = true;
(void)segto;
+
+ if(!dw_cur_list || strcmp(file_name, dw_cur_list->file_name)) {
+ if(dw_head_list) {
+ struct file_list *match = dw_head_list;
+ uint32_t idx = 0;
+
+ for (; idx < dw_num_files; idx++ ) {
+ if(!(strcmp(file_name, match->file_name))) {
+ dw_cur_list = match;
+ need_new_list = false;
+ break;
+ }
+ match = match->next;
+ }
+ }
+
+ if(need_new_list) {
+ nasm_new(dw_cur_list);
+ dw_cur_list->file = ++dw_num_files;
+ dw_cur_list->file_name = (char*)file_name;
+
+ if(!dw_head_list) {
+ dw_head_list = dw_last_list = dw_cur_list;
+ } else {
+ dw_last_list->next = dw_cur_list;
+ dw_last_list = dw_cur_list;
+ }
+ }
+ }
+
+ dbg_immcall = true;
+ cur_line = line_num;
}
static void macho_dbg_output(int type, void *param)
{
+ struct section_info *sinfo_param = (struct section_info *)param;
+ int32_t secto = sinfo_param->secto;
+ bool need_new_sect = false;
(void)type;
- (void)param;
+
+ if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
+ need_new_sect = true;
+ if(dw_head_sect) {
+ struct dw_sect_list *match = dw_head_sect;
+ uint32_t idx = 0;
+
+ for(; idx < dw_num_sects; idx++) {
+ if(match->section == secto) {
+ dw_cur_sect = match;
+ need_new_sect = false;
+ break;
+ }
+ match = match->next;
+ }
+ }
+ }
+
+ if(need_new_sect) {
+ nasm_new(dw_cur_sect);
+ dw_num_sects ++;
+ dw_cur_sect->line = dw_cur_sect->file = 1;
+ dw_cur_sect->offset = 0;
+ dw_cur_sect->next = NULL;
+ dw_cur_sect->section = secto;
+
+ if(!dw_head_sect) {
+ dw_head_sect = dw_last_sect = dw_cur_sect;
+ } else {
+ dw_last_sect->next = dw_cur_sect;
+ dw_last_sect = dw_cur_sect;
+ }
+ }
+
+ if(dbg_immcall == true) {
+ int32_t line_delta = cur_line - dw_cur_sect->line;
+ uint32_t cur_file = dw_cur_list->file;
+
+ if(cur_file != dw_cur_sect->file) {
+ dw_cur_sect->file = cur_file;
+ }
+
+ if(line_delta) {
+ dw_cur_sect->line = cur_line;
+ dw_cur_sect->offset = sinfo_param->size;
+ }
+
+ dbg_immcall = false;
+ }
}
static void macho_dbg_cleanup(void)
{
+ {
+ struct dw_sect_list *p_sect = dw_head_sect;
+ struct file_list *p_file = dw_head_list;
+ uint32_t idx = 0;
+
+ for(; idx < dw_num_sects; idx++) {
+ struct dw_sect_list *next = p_sect->next;
+ nasm_free(p_sect);
+ p_sect = next;
+ }
+
+ for(idx = 0; idx < dw_num_files; idx++) {
+ struct file_list *next = p_file->next;
+ nasm_free(p_file);
+ p_file = next;
+ }
+ }
}
#ifdef OF_MACHO32