00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #define LIBDWARF_SORTS_RELOCS
00061
00062 #if !defined(LIBDWARF_SORTS_RELOCS)
00063 #include <stdlib.h>
00064 #endif
00065
00066 #include <stdio.h>
00067 #include <elf_stuff.h>
00068 #include <elfaccess.h>
00069 #include <libelf/libelf.h>
00070 #include <libdwarf/libdwarf.h>
00071 #include <vector>
00072 #ifdef KEY
00073 #include <ctype.h>
00074 #endif
00075 #include <alloca.h>
00076
00077 #define USE_STANDARD_TYPES 1
00078 #include "defs.h"
00079 #include "erglob.h"
00080 #include "glob.h"
00081 #include "flags.h"
00082 #include "tracing.h"
00083 #include "util.h"
00084 #include "config.h"
00085 #include "config_asm.h"
00086 #include "config_list.h"
00087 #include "config_debug.h"
00088 #include "cgir.h"
00089 #include "mempool.h"
00090 #include "tn_set.h"
00091 #include "srcpos.h"
00092 #include "em_elf.h"
00093 #include "em_dwarf.h"
00094 #include "targ_const.h"
00095 #include "calls.h"
00096 #include "stblock.h"
00097 #include "data_layout.h"
00098 #include "dwarf_DST.h"
00099 #include "dwarf_DST_mem.h"
00100 #include "const.h"
00101 #include "cg.h"
00102 #include "cgtarget.h"
00103 #include "cgemit.h"
00104 #include "cgdwarf.h"
00105 #include "label_util.h"
00106 #include "vstring.h"
00107 #include "cgemit_targ.h"
00108 #include "cgdwarf_targ.h"
00109 #ifdef KEY
00110 #include "config_debug.h"
00111 #include <strings.h>
00112 #include <string.h>
00113 #endif
00114 #include "be_symtab.h"
00115
00116 BOOL Trace_Dwarf;
00117
00118 static Dwarf_P_Debug dw_dbg;
00119 static Dwarf_Error dw_error;
00120 static BOOL Disable_DST = FALSE;
00121 static DST_INFO_IDX cu_idx;
00122 static Elf64_Word cur_text_index;
00123 static DST_language Dwarf_Language;
00124
00125
00126
00127 static Dwarf_P_Die *CGD_enclosing_proc = NULL;
00128 static mINT32 CGD_enclosing_proc_max = 0;
00129
00130 #define GLOBAL_LEVEL 0
00131 #define LOCAL_LEVEL 1
00132
00133 struct CGD_SYMTAB_ENTRY {
00134 CGD_SYMTAB_ENTRY_TYPE type;
00135 Dwarf_Unsigned index;
00136 union {
00137 struct {
00138 PU_IDX pu_idx;
00139 STR_IDX name_idx;
00140
00141
00142
00143 Dwarf_Unsigned offset;
00144 Elf64_Word base_sym;
00145 } label_info;
00146 struct {
00147
00148 } elfsym_info;
00149 };
00150 #ifdef KEY
00151 Dwarf_Unsigned next;
00152 Dwarf_Unsigned CGD_Symtab_offset;
00153 #endif
00154
00155 CGD_SYMTAB_ENTRY(CGD_SYMTAB_ENTRY_TYPE entry_type, Dwarf_Unsigned idx) :
00156 type(entry_type), index(idx)
00157 #ifdef KEY
00158 , next(~0), CGD_Symtab_offset(~0)
00159 #endif
00160 {}
00161 #ifdef KEY
00162 bool next_is_null() { return next == ~0; }
00163 #endif
00164 };
00165
00166 std::vector <CGD_SYMTAB_ENTRY, mempool_allocator<CGD_SYMTAB_ENTRY> > CGD_Symtab;
00167
00168 #ifdef KEY
00169
00170 hash_map<PU_IDX, Dwarf_Unsigned> PU_IDX_To_CGD_SYMTAB_OFFSET;
00171
00172 static DST_INFO_IDX Current_Top_Level_Idx = DST_INVALID_IDX;
00173 #endif
00174
00175 #if defined(BUILD_OS_DARWIN)
00176
00177
00178
00179 static void
00180 emit_difference(FILE *asm_file, const char *reloc_name, const char *sym1,
00181 const char *sym2) {
00182 #define DIFF_SYMS ".DIFF.%s.%s"
00183 fprintf(asm_file, "\t.set " DIFF_SYMS ", %s - %s\n", sym1, sym2, sym1, sym2);
00184 fprintf(asm_file, "\t%s\t" DIFF_SYMS "\n", reloc_name, sym1, sym2);
00185 }
00186
00187
00188
00189
00190
00191
00192 static void
00193 gen_debug_line_section_header(FILE *asm_file, const char *section_name) {
00194 static int done;
00195 if (!done) {
00196 done = 1;
00197 fprintf(asm_file, "\n\t%s %s\n%s:\n", AS_SECTION,
00198 map_section_name(section_name), section_name);
00199 }
00200 }
00201 #endif
00202
00203 Dwarf_Unsigned Cg_Dwarf_Symtab_Entry(CGD_SYMTAB_ENTRY_TYPE type,
00204 Dwarf_Unsigned index,
00205 Dwarf_Unsigned pu_base_sym_idx,
00206 PU_IDX pu,
00207 char *label_name,
00208 Dwarf_Unsigned last_offset)
00209 {
00210 if (type == CGD_LABIDX && pu == (PU_IDX) 0) {
00211 pu = ST_pu(Get_Current_PU_ST());
00212 }
00213 #ifdef KEY
00214
00215
00216 CGD_SYMTAB_ENTRY *p;
00217 Dwarf_Unsigned idx = PU_IDX_To_CGD_SYMTAB_OFFSET[pu];
00218 for (p = &CGD_Symtab[idx]; !p->next_is_null(); p = &CGD_Symtab[p->next])
00219 #else
00220 std::vector <CGD_SYMTAB_ENTRY,
00221 mempool_allocator<CGD_SYMTAB_ENTRY> >::iterator p;
00222 for (p = CGD_Symtab.begin(); p != CGD_Symtab.end(); ++p)
00223 #endif
00224 {
00225 if (p->type == type &&
00226 p->index == index) {
00227 switch (type) {
00228 case CGD_LABIDX:
00229 if (p->label_info.pu_idx == pu) {
00230 #ifdef KEY
00231 return p->CGD_Symtab_offset;
00232 #else
00233 return p - CGD_Symtab.begin();
00234 #endif
00235 }
00236 break;
00237 case CGD_ELFSYM:
00238 #ifdef KEY
00239 return p->CGD_Symtab_offset;
00240 #else
00241 return p - CGD_Symtab.begin();
00242 #endif
00243 default:
00244 Fail_FmtAssertion("Illegal CGD_Symtab entry type");
00245 break;
00246 }
00247 }
00248 }
00249 #ifdef KEY
00250 CGD_SYMTAB_ENTRY new_entry = CGD_SYMTAB_ENTRY(type, index);
00251 new_entry.next = PU_IDX_To_CGD_SYMTAB_OFFSET[pu];
00252 new_entry.CGD_Symtab_offset = CGD_Symtab.size();
00253 PU_IDX_To_CGD_SYMTAB_OFFSET[pu] = new_entry.CGD_Symtab_offset;
00254 CGD_Symtab.push_back(new_entry);
00255 #else
00256 CGD_Symtab.push_back(CGD_SYMTAB_ENTRY(type, index));
00257 #endif
00258
00259 if (Trace_Dwarf) {
00260 fprintf(TFile,
00261 #if defined(BUILD_OS_DARWIN)
00262 "New CGD_Symtab entry: %lu --> (CGD_%s,%llu)\n",
00263 (long unsigned int) (CGD_Symtab.size() - 1),
00264 #else
00265 "New CGD_Symtab entry: %u --> (CGD_%s,%llu)\n",
00266 (UINT32)(CGD_Symtab.size() - 1),
00267 #endif
00268 (type == CGD_LABIDX ? "LABIDX" : "ELFSYM"),
00269 (UINT64)index);
00270 }
00271 Dwarf_Unsigned handle = CGD_Symtab.size() - 1;
00272 if (type == CGD_LABIDX) {
00273
00274 CGD_Symtab[handle].label_info.pu_idx = pu;
00275 if (label_name == NULL) {
00276 #ifdef KEY
00277 if (LABEL_IDX_level(index) == 0)
00278 index = make_LABEL_IDX(index, CURRENT_SYMTAB);
00279 #endif
00280 CGD_Symtab[handle].label_info.name_idx = LABEL_name_idx(index);
00281 CGD_Symtab[handle].label_info.offset = Get_Label_Offset(index);
00282 }
00283 else {
00284 STR_IDX lstr = Save_Str(label_name);
00285 CGD_Symtab[handle].label_info.name_idx = lstr;
00286 CGD_Symtab[handle].label_info.offset = last_offset;
00287 }
00288 CGD_Symtab[handle].label_info.base_sym = pu_base_sym_idx;
00289 if (Trace_Dwarf) {
00290 STR_IDX sidx = CGD_Symtab[handle].label_info.name_idx;
00291 fprintf(TFile,
00292 "pu_idx: %d; label: %d %s; ofst: %llu; base: %u\n",
00293 CGD_Symtab[handle].label_info.pu_idx,
00294 (INT)sidx,
00295 Index_To_Str(sidx),
00296 (UINT64)CGD_Symtab[handle].label_info.offset,
00297 CGD_Symtab[handle].label_info.base_sym);
00298 }
00299 FmtAssert(pu_base_sym_idx != 0,
00300 ("ELF symbol for base of label's section must be specified"));
00301 }
00302 else if (type == CGD_ELFSYM) {
00303
00304 }
00305 else {
00306 Fail_FmtAssertion("Illegal CGD_Symtab entry type");
00307 }
00308 return handle;
00309 }
00310
00311 Dwarf_Unsigned Cg_Dwarf_Enter_Elfsym(Elf64_Word index)
00312 {
00313 return Cg_Dwarf_Symtab_Entry(CGD_ELFSYM, index);
00314 }
00315
00316 Elf64_Word Cg_Dwarf_Translate_Symidx(Dwarf_Unsigned idx_from_sym_reloc)
00317 {
00318 Is_True(CGD_Symtab.size() > idx_from_sym_reloc,
00319 ("Cg_Dwarf_Translate_Symidx: Index %llu out of bounds (%lu)",
00320 idx_from_sym_reloc, CGD_Symtab.size()));
00321 if (Trace_Dwarf) {
00322 fprintf(TFile, "Translating %llu ", (UINT64)idx_from_sym_reloc);
00323 fflush(TFile);
00324 fprintf(TFile, "to %llu\n", (UINT64)CGD_Symtab[idx_from_sym_reloc].index);
00325 }
00326 Is_True(CGD_Symtab[idx_from_sym_reloc].type == CGD_ELFSYM,
00327 ("Cg_Dwarf_Translate_Symidx: Unexpected entry type"));
00328 return CGD_Symtab[idx_from_sym_reloc].index;
00329 }
00330
00331 Elf64_Word Cg_Dwarf_Translate_Offset(Dwarf_Unsigned idx_from_sym_reloc)
00332 {
00333 Is_True(CGD_Symtab.size() > idx_from_sym_reloc,
00334 ("Cg_Dwarf_Translate_Offset: Index %llu out of bounds (%lu)",
00335 idx_from_sym_reloc, CGD_Symtab.size()));
00336 if (Trace_Dwarf) {
00337 fprintf(TFile, "Translating %llu ", (UINT64)idx_from_sym_reloc);
00338 fflush(TFile);
00339 fprintf(TFile, "through index %llu ",
00340 (UINT64)CGD_Symtab[idx_from_sym_reloc].index);
00341 fprintf(TFile, "to %lld\n",
00342 (INT64)Get_Label_Offset(CGD_Symtab[idx_from_sym_reloc].index));
00343 }
00344 Is_True(CGD_Symtab[idx_from_sym_reloc].type == CGD_LABIDX,
00345 ("Cg_Dward_Translate_Offset: Unexpected entry type"));
00346 return Get_Label_Offset(CGD_Symtab[idx_from_sym_reloc].index);
00347 }
00348
00349 void
00350 Cg_Dwarf_Translate_To_Elf(Dwarf_Unsigned idx_from_sym_reloc,
00351 Dwarf_Unsigned *elf_symbol,
00352 Dwarf_Unsigned *elf_offset)
00353 {
00354 Is_True(CGD_Symtab.size() > idx_from_sym_reloc,
00355 ("Cg_Dwarf_Translate_Offset: Index %llu out of bounds (%lu)",
00356 idx_from_sym_reloc, CGD_Symtab.size()));
00357 if (Trace_Dwarf) {
00358 fprintf(TFile, "Translating %llu ", (UINT64)idx_from_sym_reloc);
00359 fflush(TFile);
00360 fprintf(TFile, "through index %llu ",
00361 (UINT64)CGD_Symtab[idx_from_sym_reloc].index);
00362 }
00363 if (CGD_Symtab[idx_from_sym_reloc].type == CGD_LABIDX) {
00364 *elf_symbol = CGD_Symtab[idx_from_sym_reloc].label_info.base_sym;
00365 *elf_offset = CGD_Symtab[idx_from_sym_reloc].label_info.offset;
00366 if (Trace_Dwarf) {
00367 fprintf(TFile, "to elfsym %s + 0x%llx\n",
00368 Em_Get_Symbol_Name(*elf_symbol), (UINT64)(*elf_offset));
00369 }
00370 }
00371 else {
00372 Is_True(CGD_Symtab[idx_from_sym_reloc].type == CGD_ELFSYM,
00373 ("illegal CGD_Symtab entry type"));
00374 *elf_symbol = CGD_Symtab[idx_from_sym_reloc].index;
00375 *elf_offset = 0;
00376 if (Trace_Dwarf) {
00377 fprintf(TFile, "to elfsym %s\n",
00378 Em_Get_Symbol_Name(*elf_symbol));
00379 }
00380 }
00381 }
00382
00383
00384
00385
00386 char *
00387 Cg_Dwarf_Name_From_Handle(Dwarf_Unsigned idx)
00388 {
00389 Is_True(CGD_Symtab.size() > idx,
00390 ("Cg_Dwarf_Name_From_Handle: Index %llu out of bounds (%lu)",
00391 idx, CGD_Symtab.size()));
00392 if (CGD_Symtab[idx].type == CGD_ELFSYM) {
00393 return Em_Get_Symbol_Name(CGD_Symtab[idx].index);
00394 }
00395 else {
00396
00397 STR_IDX sidx = CGD_Symtab[idx].label_info.name_idx;
00398 return Index_To_Str(sidx);
00399 }
00400 }
00401
00402 #define put_flag(flag, die) dwarf_add_AT_flag(dw_dbg, die, flag, 1, &dw_error)
00403
00404 static ST *
00405 Get_ST_From_DST (DST_ASSOC_INFO assoc_info)
00406 {
00407 ST *st;
00408 st = &St_Table(
00409 DST_ASSOC_INFO_st_level(assoc_info),
00410 DST_ASSOC_INFO_st_index(assoc_info) );
00411 FmtAssert ((st != NULL),
00412 ("Get_ST_From_DST: bad dst info from fe? assoc_info = (%d,%d)",
00413 DST_ASSOC_INFO_st_level(assoc_info),
00414 DST_ASSOC_INFO_st_index(assoc_info) ));
00415 return st;
00416 }
00417
00418
00419 static Dwarf_P_Die get_ref_die (DST_INFO_IDX ref_idx)
00420 {
00421 DST_INFO *info;
00422 Dwarf_P_Die ref_die;
00423
00424 info = DST_INFO_IDX_TO_PTR(ref_idx);
00425 FmtAssert(DST_INFO_tag(info) != 0,
00426 ("get_ref_die found 0 tag for idx %d,%d",
00427 ref_idx.block_idx, ref_idx.byte_idx));
00428 ref_die = (Dwarf_P_Die) DST_INFO_dieptr (info);
00429 if (ref_die == NULL) {
00430 ref_die = dwarf_new_die (dw_dbg, DST_INFO_tag(info), NULL, NULL,
00431 NULL, NULL, &dw_error);
00432 DST_INFO_dieptr(info) = ref_die;
00433 if (Trace_Dwarf) {
00434 fprintf (TFile,"NEW ref die for [%d,%d]: %p, tag:%d\n",
00435 ref_idx.block_idx, ref_idx.byte_idx, ref_die, DST_INFO_tag(info));
00436 }
00437 }
00438 return ref_die;
00439 }
00440
00441
00442 static void
00443 put_reference (DST_INFO_IDX ref_idx, Dwarf_Half ref_attr, Dwarf_P_Die die)
00444 {
00445 Dwarf_P_Die ref_die;
00446
00447 if (DST_IS_NULL(ref_idx)) return;
00448
00449
00450 FmtAssert ( ! DST_IS_FOREIGN_OBJ(ref_idx),
00451 ("Dwarf reference to foreign object"));
00452 ref_die = get_ref_die (ref_idx);
00453 dwarf_add_AT_reference (dw_dbg, die, ref_attr, ref_die, &dw_error);
00454
00455 }
00456
00457
00458 typedef enum {
00459 pb_none,
00460 pb_pubname,
00461 pb_funcname,
00462 pb_weakname,
00463 pb_varname,
00464 pb_typename
00465 } which_pb;
00466
00467
00468
00469
00470
00471 static void
00472 put_pubname (char *name, Dwarf_P_Die die, which_pb pb_type)
00473 {
00474 switch (pb_type) {
00475 case pb_pubname:
00476 dwarf_add_pubname (dw_dbg, die, name, &dw_error);
00477 break;
00478 case pb_funcname:
00479 dwarf_add_funcname (dw_dbg, die, name, &dw_error);
00480 break;
00481 case pb_weakname:
00482 dwarf_add_weakname (dw_dbg, die, name, &dw_error);
00483 break;
00484 case pb_varname:
00485 if (Debug_Level > 0) dwarf_add_varname (dw_dbg, die, name, &dw_error);
00486 break;
00487 case pb_typename:
00488 if (Debug_Level > 0) dwarf_add_typename (dw_dbg, die, name, &dw_error);
00489 break;
00490 default:
00491 break;
00492 }
00493 }
00494
00495
00496 static void
00497 put_string (DST_STR_IDX str_idx, Dwarf_Half str_attr, Dwarf_P_Die die)
00498 {
00499 char *name;
00500
00501 if (DST_IS_NULL(str_idx)) return;
00502
00503 name = DST_STR_IDX_TO_PTR (str_idx);
00504 dwarf_add_AT_string (dw_dbg, die, str_attr, name, &dw_error);
00505 }
00506
00507
00508 static void
00509 put_name (DST_STR_IDX str_idx, Dwarf_P_Die die, which_pb pb_type)
00510 {
00511 char *name;
00512
00513 if (DST_IS_NULL(str_idx)) return;
00514
00515 name = DST_STR_IDX_TO_PTR (str_idx);
00516 put_string (str_idx, DW_AT_name, die);
00517 put_pubname (name, die, pb_type);
00518 if (Trace_Dwarf) {
00519 fprintf (TFile,"AT_name attribute: %s\n", DST_STR_IDX_TO_PTR (str_idx));
00520 }
00521 }
00522
00523
00524
00525 static void
00526 put_decl(USRCPOS decl, Dwarf_P_Die die)
00527 {
00528 if (USRCPOS_filenum(decl) != 0)
00529
00530 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_decl_file,
00531 (UINT32)USRCPOS_filenum(decl), &dw_error);
00532 if (USRCPOS_linenum(decl) != 0)
00533 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_decl_line,
00534 (UINT32)USRCPOS_linenum(decl), &dw_error);
00535 if (USRCPOS_column(decl) != 0)
00536 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_decl_column,
00537 (UINT32)USRCPOS_column(decl), &dw_error);
00538 }
00539
00540 static void
00541 put_const_attribute (DST_CONST_VALUE cval, Dwarf_Half ref_attr, Dwarf_P_Die die)
00542 {
00543 switch (DST_CONST_VALUE_form(cval)) {
00544 case DST_FORM_STRING:
00545 put_string (DST_CONST_VALUE_form_string(cval), ref_attr, die);
00546 break;
00547 #ifdef TARG_IA64
00548 case DST_FORM_DATA1:
00549 dwarf_add_AT_unsigned_const (dw_dbg, die, ref_attr,
00550 DST_CONST_VALUE_form_data1(cval), &dw_error);
00551 break;
00552 case DST_FORM_DATA2:
00553 dwarf_add_AT_unsigned_const (dw_dbg, die, ref_attr,
00554 DST_CONST_VALUE_form_data2(cval), &dw_error);
00555 break;
00556 case DST_FORM_DATA4:
00557 dwarf_add_AT_unsigned_const (dw_dbg, die, ref_attr,
00558 DST_CONST_VALUE_form_data4(cval), &dw_error);
00559 break;
00560 case DST_FORM_DATA8:
00561 dwarf_add_AT_unsigned_const (dw_dbg, die, ref_attr,
00562 DST_CONST_VALUE_form_data8(cval), &dw_error);
00563 break;
00564 #else
00565
00566 case DST_FORM_DATA1:
00567 dwf_add_AT_unsigned_const_ext (dw_dbg, die, ref_attr,
00568 DST_CONST_VALUE_form_data1(cval),
00569 &dw_error, 1);
00570 break;
00571 case DST_FORM_DATA2:
00572 dwf_add_AT_unsigned_const_ext (dw_dbg, die, ref_attr,
00573 DST_CONST_VALUE_form_data2(cval),
00574 &dw_error, 2);
00575 break;
00576 case DST_FORM_DATA4:
00577 dwf_add_AT_unsigned_const_ext (dw_dbg, die, ref_attr,
00578 DST_CONST_VALUE_form_data4(cval),
00579 &dw_error, 4);
00580 break;
00581 case DST_FORM_DATA8:
00582 dwf_add_AT_unsigned_const_ext (dw_dbg, die, ref_attr,
00583 DST_CONST_VALUE_form_data8(cval),
00584 &dw_error, 8);
00585 break;
00586 case DST_FORM_DATAC4:
00587 dwf_add_AT_complex_const (dw_dbg, die, ref_attr,
00588 DST_CONST_VALUE_form_crdata4(cval),
00589 DST_CONST_VALUE_form_cidata4(cval),
00590 &dw_error, 4);
00591 break;
00592 case DST_FORM_DATAC8:
00593 dwf_add_AT_complex_const (dw_dbg, die, ref_attr,
00594 DST_CONST_VALUE_form_crdata8(cval),
00595 DST_CONST_VALUE_form_cidata8(cval),
00596 &dw_error, 8);
00597 break;
00598 #endif //TARG_IA64
00599 }
00600 }
00601
00602
00603 static void
00604 put_dopetype (DST_INFO_IDX dope_idx, DST_flag flag, Dwarf_P_Die die)
00605 {
00606 #ifdef TARG_X8664
00607 return;
00608 #else
00609 if (DST_IS_f90_pointer(flag))
00610 put_reference (dope_idx, DW_AT_MIPS_ptr_dopetype, die);
00611 if (DST_IS_allocatable(flag))
00612 put_reference (dope_idx, DW_AT_MIPS_allocatable_dopetype, die);
00613 if (DST_IS_assumed_shape(flag))
00614 put_reference (dope_idx, DW_AT_MIPS_assumed_shape_dopetype, die);
00615 #endif
00616 }
00617
00618
00619
00620
00621
00622
00623 static void
00624 put_compile_unit(DST_COMPILE_UNIT *attr, Dwarf_P_Die die)
00625 {
00626 put_name (DST_COMPILE_UNIT_name(attr), die, pb_none);
00627 #ifdef TARG_SL
00628
00629
00630
00631
00632
00633
00634 char *name;
00635 if (DST_IS_NULL(DST_COMPILE_UNIT_name(attr)))
00636 name = NULL;
00637 else
00638 name = DST_STR_IDX_TO_PTR (DST_COMPILE_UNIT_name(attr));
00639 if ((name != NULL) && (name[0] == '/'))
00640
00641 ;
00642 else
00643 put_string (DST_COMPILE_UNIT_comp_dir(attr), DW_AT_comp_dir, die);
00644 #else
00645 put_string (DST_COMPILE_UNIT_comp_dir(attr), DW_AT_comp_dir, die);
00646 #endif
00647 if (DEBUG_Optimize_Space && Debug_Level == 0)
00648
00649 dwarf_add_AT_string (dw_dbg, die, DW_AT_producer, "", &dw_error);
00650 else
00651 put_string (DST_COMPILE_UNIT_producer(attr), DW_AT_producer, die);
00652 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_language,
00653 DST_COMPILE_UNIT_language(attr), &dw_error);
00654 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_identifier_case,
00655 DST_COMPILE_UNIT_identifier_case(attr), &dw_error);
00656
00657 if (FILE_INFO_has_inlines (File_info))
00658 put_flag (DW_AT_MIPS_has_inlines, die);
00659 }
00660
00661 static BOOL
00662 subprogram_def_is_inlined (DST_SUBPROGRAM *attr)
00663 {
00664 switch (DST_SUBPROGRAM_def_inline(attr)) {
00665 case DW_INL_inlined:
00666 case DW_INL_declared_inlined:
00667 return TRUE;
00668 default:
00669 return FALSE;
00670 }
00671 }
00672
00673 static void
00674 put_subprogram(DST_flag flag,
00675 DST_SUBPROGRAM *attr,
00676 Dwarf_P_Die die)
00677 {
00678 Dwarf_P_Expr expr;
00679
00680 if (DST_IS_memdef(flag)) {
00681 ErrMsg (EC_Unimplemented,
00682 " put_subprogram: a class member with AT_specification!");
00683 }
00684 else if (DST_IS_declaration(flag)) {
00685
00686
00687
00688
00689
00690 if (!DST_IS_NULL(DST_SUBPROGRAM_decl_origin(attr))) {
00691 if (!DST_IS_NULL(DST_SUBPROGRAM_decl_name(attr))) {
00692 put_pubname (DST_STR_IDX_TO_PTR(DST_SUBPROGRAM_decl_name(attr)),
00693 get_ref_die (DST_SUBPROGRAM_decl_origin(attr)),
00694 pb_weakname);
00695 }
00696 }
00697 put_decl(DST_SUBPROGRAM_decl_decl(attr), die);
00698 put_name (DST_SUBPROGRAM_decl_name(attr), die, pb_none);
00699 put_reference (DST_SUBPROGRAM_decl_type(attr), DW_AT_type, die);
00700 put_flag (DW_AT_declaration, die);
00701 if (DST_IS_external(flag)) put_flag (DW_AT_external, die);
00702 if (DST_IS_prototyped(flag)) put_flag (DW_AT_prototyped, die);
00703 if (DST_SUBPROGRAM_decl_virtuality(attr) != DW_VIRTUALITY_none) {
00704 dwarf_add_AT_unsigned_const(dw_dbg, die, DW_AT_virtuality,
00705 DST_SUBPROGRAM_decl_virtuality(attr),
00706 &dw_error);
00707 expr = dwarf_new_expr(dw_dbg, &dw_error);
00708 dwarf_add_expr_gen(expr,
00709 DW_OP_const2u,
00710 DST_SUBPROGRAM_decl_vtable_elem_location(attr),
00711 0,
00712 &dw_error);
00713 dwarf_add_AT_location_expr(dw_dbg, die, DW_AT_vtable_elem_location,
00714 expr, &dw_error);
00715 }
00716 put_string (DST_SUBPROGRAM_decl_linkage_name(attr),
00717 DW_AT_MIPS_linkage_name, die);
00718
00719 switch (DST_SUBPROGRAM_decl_inline(attr)) {
00720 case DW_INL_inlined:
00721 case DW_INL_declared_inlined:
00722 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_inline,
00723 DST_SUBPROGRAM_decl_inline(attr), &dw_error);
00724 break;
00725 }
00726 }
00727 else {
00728 char *pubname;
00729
00730 put_decl(DST_SUBPROGRAM_def_decl(attr), die);
00731
00732 if (!DST_IS_NULL(DST_SUBPROGRAM_def_pubname(attr))) {
00733 put_name (DST_SUBPROGRAM_def_name(attr), die, pb_none);
00734 pubname = DST_STR_IDX_TO_PTR (DST_SUBPROGRAM_def_pubname(attr));
00735 dwarf_add_pubname (dw_dbg, die, pubname, &dw_error);
00736 }
00737 else {
00738 put_name (DST_SUBPROGRAM_def_name(attr),
00739 die,
00740 DST_IS_external(flag) ? pb_pubname : pb_funcname);
00741 }
00742 #ifdef KEY
00743
00744
00745
00746
00747
00748
00749
00750
00751 if (DST_IS_NULL(DST_SUBPROGRAM_def_type(attr)) &&
00752 (Dwarf_Language == DW_LANG_Fortran77 ||
00753 Dwarf_Language == DW_LANG_Fortran90) &&
00754 !DST_IS_NULL(Current_Top_Level_Idx)) {
00755 DST_INFO_IDX child_idx;
00756 for (child_idx = DST_first_child (Current_Top_Level_Idx);
00757 !DST_IS_NULL(child_idx);
00758 child_idx = DST_INFO_sibling(DST_INFO_IDX_TO_PTR(child_idx))) {
00759 if (!DST_IS_NULL(child_idx)) {
00760 DST_INFO *child_info = DST_INFO_IDX_TO_PTR (child_idx);
00761 if (child_info &&
00762 DST_INFO_tag(child_info) == DW_TAG_variable) {
00763 DST_ATTR_IDX child_attr_idx = DST_INFO_attributes(child_info);
00764 DST_VARIABLE *child_attr =
00765 DST_ATTR_IDX_TO_PTR(child_attr_idx, DST_VARIABLE);
00766 if (child_attr) {
00767 DST_STR_IDX child_str_idx = DST_VARIABLE_def_name(child_attr);
00768 if (!DST_IS_NULL(child_str_idx)) {
00769 ST *pu_st = Get_ST_From_DST(DST_SUBPROGRAM_def_st(attr));
00770 char *pu_name = ST_name(pu_st);
00771 char *variable_name = DST_STR_IDX_TO_PTR(child_str_idx);
00772 if (strncasecmp(variable_name, pu_name,
00773 strlen(variable_name)) == 0)
00774 put_reference (DST_VARIABLE_decl_type(child_attr),
00775 DW_AT_type, die);
00776 }
00777 }
00778 break;
00779 }
00780 }
00781 }
00782 } else
00783 #endif
00784 put_reference (DST_SUBPROGRAM_def_type(attr), DW_AT_type, die);
00785 if (DST_IS_external(flag)) put_flag (DW_AT_external, die);
00786 if (DST_IS_prototyped(flag)) put_flag (DW_AT_prototyped, die);
00787
00788 put_reference (DST_SUBPROGRAM_def_specification(attr),
00789 DW_AT_specification, die);
00790 if (DST_SUBPROGRAM_def_virtuality(attr) != DW_VIRTUALITY_none) {
00791 dwarf_add_AT_unsigned_const(dw_dbg, die, DW_AT_virtuality,
00792 DST_SUBPROGRAM_def_virtuality(attr),
00793 &dw_error);
00794 expr = dwarf_new_expr(dw_dbg, &dw_error);
00795 dwarf_add_expr_gen(expr,
00796 DW_OP_const2u,
00797 DST_SUBPROGRAM_def_vtable_elem_location(attr),
00798 0,
00799 &dw_error);
00800 dwarf_add_AT_location_expr(dw_dbg, die, DW_AT_vtable_elem_location,
00801 expr, &dw_error);
00802 }
00803
00804 put_string (DST_SUBPROGRAM_def_linkage_name(attr),
00805 DW_AT_MIPS_linkage_name, die);
00806 if (!DST_IS_NULL(DST_SUBPROGRAM_def_clone_origin(attr))) {
00807 put_reference (DST_SUBPROGRAM_def_clone_origin(attr),
00808 DW_AT_MIPS_clone_origin, die);
00809 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_calling_convention,
00810 DW_CC_nocall, &dw_error);
00811 }
00812 if (subprogram_def_is_inlined(attr)) {
00813 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_inline,
00814 DST_SUBPROGRAM_def_inline(attr), &dw_error);
00815 }
00816 if (PU_has_inlines(Get_Current_PU()))
00817 put_flag (DW_AT_MIPS_has_inlines, die);
00818 }
00819 }
00820
00821
00822 static Elf64_Word
00823 get_elfindex_from_ASSOC_INFO (DST_ASSOC_INFO assoc_info)
00824 {
00825 ST *st;
00826 st = Get_ST_From_DST (assoc_info);
00827 return EMT_Put_Elf_Symbol(st);
00828 }
00829
00830 static mINT32
00831 get_ofst_from_ASSOC_INFO (DST_ASSOC_INFO assoc_info)
00832 {
00833 ST *st;
00834 st = Get_ST_From_DST (assoc_info);
00835 return (st != NULL) ? ST_ofst(st) : 0;
00836 }
00837
00838
00839
00840 static mINT32
00841 get_ofst_from_label_ASSOC_INFO (DST_ASSOC_INFO assoc_info)
00842 {
00843 ST *st;
00844 if (DST_ASSOC_INFO_st_index(assoc_info) == 0) {
00845
00846
00847 st = &St_Table(
00848 DST_ASSOC_INFO_st_level(assoc_info),
00849 DST_ASSOC_INFO_st_index(assoc_info) );
00850 } else {
00851 LABEL_IDX lab;
00852 lab = DST_ASSOC_INFO_st_index(assoc_info);
00853 FmtAssert ((lab > 0 && lab <= LABEL_Table_Size(DST_ASSOC_INFO_st_level(assoc_info))),
00854 ("get_ofst_from_label_ASSOC_INFO: bad dst info from fe? (%d,%d)",
00855 DST_ASSOC_INFO_st_level(assoc_info),
00856 DST_ASSOC_INFO_st_index(assoc_info) ));
00857 return Get_Label_Offset(lab);
00858 }
00859 FmtAssert ((st != NULL),
00860 ("get_ofst_from_label_ASSOC_INFO: bad dst info from fe? (%d,%d)",
00861 DST_ASSOC_INFO_st_level(assoc_info),
00862 DST_ASSOC_INFO_st_index(assoc_info) ));
00863 return (st != NULL) ? ST_ofst(st) : 0;
00864 }
00865
00866 extern INT
00867 Offset_from_FP (ST *st)
00868 {
00869 ST *base_st;
00870 INT64 base_ofst;
00871 Allocate_Object(st);
00872 Base_Symbol_And_Offset (st, &base_st, &base_ofst);
00873
00874 if (base_st == SP_Sym) {
00875 return (base_ofst - Frame_Len);
00876 }
00877 else if (base_st == FP_Sym) {
00878 return base_ofst;
00879 }
00880 else {
00881 Is_True(FALSE, ("symbol %s is not allocated", ST_name(st)));
00882 return 0;
00883 }
00884 }
00885
00886
00887
00888
00889
00890 static void
00891 put_location (
00892 DST_ASSOC_INFO assoc_info,
00893 INT offs,
00894 DST_flag flag,
00895 Dwarf_P_Die die,
00896 Dwarf_Half loc_attr)
00897 {
00898 Dwarf_P_Expr expr;
00899 ST *st;
00900 ST *base_st;
00901 INT64 base_ofst;
00902 BOOL deref;
00903
00904 st = Get_ST_From_DST (assoc_info);
00905 if (ST_sclass(st) == SCLASS_FORMAL_REF)
00906 st = Get_ST_formal_ref_base(st);
00907 if (st == NULL) return;
00908 if (ST_is_not_used(st)) return;
00909 #ifdef KEY // Ignore asm string names. Bug 7604.
00910 if (ST_sym_class(st) == CLASS_NAME) return;
00911 #endif
00912
00913 Base_Symbol_And_Offset (st, &base_st, &base_ofst);
00914
00915 #ifdef TARG_IA64
00916 if (ST_is_not_used(base_st)) return;
00917 #endif
00918 #ifdef TARG_NVISA
00919
00920
00921
00922
00923
00924 if ((ST_sclass(st) == SCLASS_FSTATIC || ST_sclass(st) == SCLASS_PSTATIC)
00925 && (ST_export(st) == EXPORT_LOCAL || ST_export(st) == EXPORT_LOCAL_INTERNAL)
00926 && ! BE_ST_referenced(st)
00927 && strncmp(ST_name(st), "__cuda", 6) == 0)
00928 return;
00929 #endif
00930
00931 deref = FALSE;
00932 if (DST_IS_deref(flag))
00933 deref = TRUE;
00934
00935 expr = dwarf_new_expr (dw_dbg, &dw_error);
00936
00937 if (st == base_st && ST_class(st) != CLASS_BLOCK
00938 && ST_sclass(st) != SCLASS_COMMON && ST_sclass(st) != SCLASS_EXTERN)
00939 {
00940
00941 #ifndef KEY
00942 return;
00943 #else
00944
00945
00946
00947 Allocate_Object(st);
00948 Base_Symbol_And_Offset (st, &base_st, &base_ofst);
00949 #endif
00950 }
00951
00952 switch (ST_sclass(st)) {
00953 case SCLASS_FORMAL:
00954 if (base_st != SP_Sym && base_st != FP_Sym) {
00955
00956 #ifdef TARG_NVISA
00957
00958 dwarf_add_expr_addr_b (expr, offs,
00959 Cg_Dwarf_Symtab_Entry(CGD_ELFSYM,
00960 EMT_Put_Elf_Symbol(st)),
00961 &dw_error);
00962 if (Trace_Dwarf) {
00963 fprintf (TFile,"LocExpr: symbol = %s, offset = %d\n", ST_name(st), offs);
00964 }
00965 #else
00966 dwarf_add_expr_addr_b (expr,
00967 #ifdef KEY
00968
00969
00970 base_ofst + offs,
00971 #else
00972 ST_ofst(st) + offs,
00973 #endif
00974 Cg_Dwarf_Symtab_Entry(CGD_ELFSYM,
00975 EMT_Put_Elf_Symbol(base_st)),
00976 &dw_error);
00977 if (Trace_Dwarf) {
00978 fprintf (TFile,"LocExpr: symbol = %s, offset = %lld\n",
00979 #ifdef KEY
00980 ST_name(base_st), base_ofst + ST_ofst(st) + offs);
00981 #else
00982 ST_name(base_st), ST_ofst(st) + offs);
00983 #endif
00984 }
00985 #endif // NVISA
00986 break;
00987 }
00988
00989
00990 case SCLASS_AUTO:
00991
00992 if (DST_IS_base_deref(flag)) {
00993
00994 dwarf_add_expr_gen (expr, DW_OP_fbreg, Offset_from_FP(st),
00995 0, &dw_error);
00996
00997 dwarf_add_expr_gen (expr, DW_OP_deref, 0,0, &dw_error);
00998 dwarf_add_expr_gen (expr, DW_OP_plus_uconst, offs, 0, &dw_error);
00999
01000 } else {
01001
01002 dwarf_add_expr_gen (expr, DW_OP_fbreg, Offset_from_FP(st) + offs,
01003 0, &dw_error);
01004 }
01005 if (Trace_Dwarf) {
01006 fprintf (TFile,"LocExpr: DW_OP_fbreg, offset = %d\n",
01007 Offset_from_FP(st) + offs);
01008 }
01009 break;
01010
01011 case SCLASS_CPLINIT:
01012 case SCLASS_EH_REGION:
01013 case SCLASS_EH_REGION_SUPP:
01014 case SCLASS_DGLOBAL:
01015 case SCLASS_UGLOBAL:
01016 case SCLASS_FSTATIC:
01017 case SCLASS_PSTATIC:
01018 #ifdef TARG_NVISA
01019 if (FALSE) {
01020 #else
01021 if (base_st != NULL) {
01022 #endif
01023 dwarf_add_expr_addr_b (expr,
01024 #ifdef KEY
01025
01026
01027 base_ofst + offs,
01028 #else
01029 ST_ofst(st) + offs,
01030 #endif
01031 Cg_Dwarf_Symtab_Entry(CGD_ELFSYM,
01032 EMT_Put_Elf_Symbol(base_st)),
01033 &dw_error);
01034 if (Trace_Dwarf) {
01035 fprintf (TFile,"LocExpr: symbol = %s, offset = %lld\n",
01036 #ifdef KEY
01037 ST_name(base_st), base_ofst + ST_ofst(st) + offs);
01038 #else
01039 ST_name(base_st), ST_ofst(st) + offs);
01040 #endif
01041 }
01042 }
01043 else {
01044 dwarf_add_expr_addr_b (expr, offs,
01045 Cg_Dwarf_Symtab_Entry(CGD_ELFSYM,
01046 EMT_Put_Elf_Symbol(st)),
01047 &dw_error);
01048 if (Trace_Dwarf) {
01049 fprintf (TFile,"LocExpr: symbol = %s, offset = %d\n", ST_name(st), offs);
01050 }
01051 }
01052 break;
01053
01054 case SCLASS_COMMON:
01055 case SCLASS_EXTERN:
01056 dwarf_add_expr_addr_b (expr, offs,
01057 Cg_Dwarf_Symtab_Entry(CGD_ELFSYM,
01058 EMT_Put_Elf_Symbol(st)),
01059 &dw_error);
01060
01061 if (Trace_Dwarf) {
01062 fprintf (TFile,"LocExpr: symbol = %s, offset = %d\n", ST_name(st), offs);
01063 }
01064 break;
01065 default:
01066 #ifdef KEY
01067
01068
01069 if ((base_st == FP_Sym || base_st == SP_Sym) && ST_sclass(st) == SCLASS_UNKNOWN) {
01070 if (DST_IS_base_deref(flag)) {
01071
01072 dwarf_add_expr_gen (expr, DW_OP_fbreg, Offset_from_FP(st),
01073 0, &dw_error);
01074
01075 dwarf_add_expr_gen (expr, DW_OP_deref, 0,0, &dw_error);
01076 dwarf_add_expr_gen (expr, DW_OP_plus_uconst, offs, 0, &dw_error);
01077
01078 } else {
01079
01080 dwarf_add_expr_gen (expr, DW_OP_fbreg, Offset_from_FP(st) + offs,
01081 0, &dw_error);
01082 }
01083 break;
01084 }
01085 #endif
01086 ErrMsg (EC_Unimplemented, "put_location: sclass");
01087 return;
01088 }
01089 if (deref) {
01090 dwarf_add_expr_gen (expr, DW_OP_deref, 0, 0, &dw_error);
01091 if (Trace_Dwarf) {
01092 fprintf (TFile,"LocExpr: DW_OP_deref\n");
01093 }
01094 }
01095 dwarf_add_AT_location_expr (dw_dbg, die, loc_attr, expr, &dw_error);
01096 #ifdef TARG_NVISA
01097
01098 {
01099 INT space;
01100 if (ST_sclass(st) == SCLASS_FORMAL) space = DW_ADDR_param_space;
01101 else if (ST_in_global_mem(st)) space = DW_ADDR_global_space;
01102 else if (ST_in_shared_mem(st)) space = DW_ADDR_shared_space;
01103 else if (ST_in_local_mem(st)) space = DW_ADDR_local_space;
01104 else if (ST_in_constant_mem(st)) space = DW_ADDR_const_space;
01105 else if (ST_in_texture_mem(st)) space = DW_ADDR_tex_space;
01106 else space = DW_ADDR_none;
01107 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_address_class, space, &dw_error);
01108 }
01109 #endif
01110 return;
01111 }
01112
01113 static void
01114 put_pc_value_symbolic (Dwarf_Unsigned pc_attr,
01115 Dwarf_Unsigned pc_label,
01116 Dwarf_Addr pc_offset,
01117 Dwarf_P_Die die)
01118 {
01119 dwarf_add_AT_targ_address_b(dw_dbg,
01120 die,
01121 pc_attr,
01122 pc_offset,
01123 pc_label,
01124 &dw_error);
01125 }
01126
01127 #if 0
01128 static void
01129 put_pc_value (Dwarf_Unsigned pc_attr, INT32 pc_value, Dwarf_P_Die die)
01130 {
01131 dwarf_add_AT_targ_address(
01132 dw_dbg,
01133 die,
01134 pc_attr,
01135 pc_value,
01136 cur_text_index,
01137 &dw_error);
01138 }
01139 #endif
01140
01141 static void
01142 put_lexical_block(DST_flag flag, DST_LEXICAL_BLOCK *attr, Dwarf_P_Die die)
01143 {
01144 put_name (DST_LEXICAL_BLOCK_name(attr), die, pb_none);
01145 #if 1
01146 put_pc_value_symbolic (DW_AT_low_pc,
01147 Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
01148 (LABEL_IDX) DST_ASSOC_INFO_st_index(DST_LEXICAL_BLOCK_low_pc(attr)),
01149 cur_text_index),
01150 (Dwarf_Addr) 0,
01151 die);
01152 put_pc_value_symbolic (DW_AT_high_pc,
01153 Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
01154 (LABEL_IDX) DST_ASSOC_INFO_st_index(DST_LEXICAL_BLOCK_high_pc(attr)),
01155 cur_text_index),
01156 (Dwarf_Addr) 0,
01157 die);
01158 #else
01159 put_pc_value (DW_AT_low_pc,
01160 get_ofst_from_label_ASSOC_INFO(DST_LEXICAL_BLOCK_low_pc(attr)),
01161 die);
01162 put_pc_value (DW_AT_high_pc,
01163 get_ofst_from_label_ASSOC_INFO(DST_LEXICAL_BLOCK_high_pc(attr)),
01164 die);
01165 #endif
01166 }
01167
01168 static void
01169 put_inlined_subroutine(DST_INLINED_SUBROUTINE *attr, Dwarf_P_Die die)
01170 {
01171 #if 1
01172 put_pc_value_symbolic (DW_AT_low_pc,
01173 Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
01174 (LABEL_IDX) DST_ASSOC_INFO_st_index(DST_LEXICAL_BLOCK_low_pc(attr)),
01175 cur_text_index),
01176 (Dwarf_Addr) 0,
01177 die);
01178 put_pc_value_symbolic (DW_AT_high_pc,
01179 Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
01180 (LABEL_IDX) DST_ASSOC_INFO_st_index(DST_LEXICAL_BLOCK_high_pc(attr)),
01181 cur_text_index),
01182 (Dwarf_Addr) 0,
01183 die);
01184 #else
01185 put_pc_value (DW_AT_low_pc,
01186 get_ofst_from_label_ASSOC_INFO(DST_INLINED_SUBROUTINE_low_pc(attr)),
01187 die);
01188 put_pc_value (DW_AT_high_pc,
01189 get_ofst_from_label_ASSOC_INFO(DST_INLINED_SUBROUTINE_high_pc(attr)),
01190 die);
01191 #endif
01192
01193 if (DST_IS_FOREIGN_OBJ (DST_INLINED_SUBROUTINE_abstract_origin(attr))) {
01194
01195 put_string (
01196 DST_INLINED_SUBROUTINE_abstract_name(attr),
01197 DW_AT_MIPS_abstract_name,
01198 die);
01199 put_decl (DST_INLINED_SUBROUTINE_decl(attr), die);
01200 }
01201 else {
01202
01203 put_reference(
01204 DST_INLINED_SUBROUTINE_abstract_origin(attr),
01205 DW_AT_abstract_origin,
01206 die);
01207 }
01208 }
01209
01210 static void
01211 put_concrete_subprogram (DST_INFO_IDX abstract_idx,
01212 INT32 low_pc,
01213 INT32 high_pc,
01214 Dwarf_P_Die die)
01215 {
01216 #if 0
01217 put_pc_value (DW_AT_low_pc, low_pc, die);
01218 put_pc_value (DW_AT_high_pc, high_pc, die);
01219 #endif
01220 put_reference( abstract_idx, DW_AT_abstract_origin, die);
01221 }
01222
01223 static void
01224 put_label(DST_flag flag, DST_LABEL *attr, Dwarf_P_Die die)
01225 {
01226 put_name (DST_LABEL_name(attr), die, pb_none);
01227 dwarf_add_AT_targ_address_b (dw_dbg, die, DW_AT_low_pc,
01228 get_ofst_from_label_ASSOC_INFO(DST_LABEL_low_pc(attr)),
01229 cur_text_index, &dw_error);
01230 }
01231
01232
01233 static void
01234 put_variable(DST_flag flag, DST_VARIABLE *attr, Dwarf_P_Die die)
01235 {
01236 if (DST_IS_const(flag)) {
01237 #ifndef KEY
01238 ErrMsg (EC_Unimplemented, "put_variable: DST_IS_const");
01239 #else
01240 DST_CONSTANT *attr_tmp = (DST_CONSTANT *)attr;
01241 FmtAssert (!DST_IS_declaration(flag), ("put_constant of non-def"));
01242 put_decl(DST_CONSTANT_def_decl(attr_tmp), die);
01243 put_name (DST_CONSTANT_def_name(attr_tmp), die, pb_none);
01244 put_reference (DST_CONSTANT_def_type(attr_tmp), DW_AT_type, die);
01245 put_const_attribute (DST_CONSTANT_def_cval(attr_tmp), DW_AT_const_value, die);
01246 #endif
01247 }
01248 else if (DST_IS_memdef(flag)) {
01249 ErrMsg (EC_Unimplemented,
01250 "put_variable: a class member with AT_specification");
01251 }
01252 else if (DST_IS_declaration(flag)) {
01253 put_decl(DST_VARIABLE_decl_decl(attr), die);
01254 put_name (DST_VARIABLE_decl_name(attr), die, pb_none);
01255 put_reference (DST_VARIABLE_decl_type(attr), DW_AT_type, die);
01256 put_flag (DW_AT_declaration, die);
01257 if (DST_IS_external(flag)) put_flag (DW_AT_external, die);
01258 #ifdef KEY
01259 if (!DST_IS_NULL (DST_VARIABLE_decl_linkage_name(attr))) {
01260 put_string (DST_VARIABLE_decl_linkage_name(attr), DW_AT_MIPS_linkage_name, die) ;
01261 }
01262 #endif
01263 }
01264 else if (DST_IS_comm(flag)) {
01265 put_decl(DST_VARIABLE_comm_decl(attr), die);
01266 put_name (DST_VARIABLE_comm_name(attr), die, pb_varname);
01267 put_reference (DST_VARIABLE_comm_type(attr), DW_AT_type, die);
01268 put_dopetype (DST_VARIABLE_comm_dopetype(attr), flag, die);
01269
01270 put_location (DST_VARIABLE_comm_st(attr),
01271 (INT) DST_VARIABLE_comm_offs(attr),
01272 flag, die, DW_AT_location);
01273 if (DST_IS_external(flag)) put_flag (DW_AT_external, die);
01274 if (DST_IS_assumed_size(flag)) put_flag (DW_AT_MIPS_assumed_size, die);
01275 }
01276 else {
01277 which_pb pbtype;
01278
01279 put_decl(DST_VARIABLE_def_decl(attr), die);
01280 if (DST_IS_external(flag))
01281 pbtype = pb_pubname;
01282 else if (!DST_IS_automatic(flag))
01283 pbtype = pb_varname;
01284 else
01285 pbtype = pb_none;
01286 put_name (DST_VARIABLE_def_name(attr), die, pbtype);
01287 put_reference (DST_VARIABLE_def_type(attr), DW_AT_type, die);
01288 put_location (DST_VARIABLE_def_st(attr),
01289 (INT) DST_VARIABLE_def_offs(attr),
01290 flag, die, DW_AT_location);
01291 if (DST_IS_external(flag)) put_flag (DW_AT_external, die);
01292 if (DST_IS_assumed_size(flag)) put_flag (DW_AT_MIPS_assumed_size, die);
01293 put_dopetype (DST_VARIABLE_def_dopetype(attr), flag, die);
01294
01295 if (!DST_IS_NULL(DST_VARIABLE_def_specification(attr)))
01296 put_reference (DST_VARIABLE_def_specification(attr),
01297 DW_AT_specification, die);
01298 if ( ! DST_IS_FOREIGN_OBJ(DST_VARIABLE_def_abstract_origin(attr))) {
01299 put_reference(
01300 DST_VARIABLE_def_abstract_origin(attr),
01301 DW_AT_abstract_origin,
01302 die);
01303 }
01304
01305 #ifdef KEY
01306 if (!DST_IS_NULL (DST_VARIABLE_decl_linkage_name(attr))) {
01307 put_string (DST_VARIABLE_def_linkage_name(attr), DW_AT_MIPS_linkage_name, die) ;
01308 }
01309 #endif
01310 }
01311 }
01312
01313 static void
01314 put_constant (DST_flag flag, DST_CONSTANT *attr, Dwarf_P_Die die)
01315 {
01316 FmtAssert (!DST_IS_declaration(flag), ("put_constant of non-def"));
01317 put_decl(DST_CONSTANT_def_decl(attr), die);
01318 put_name (DST_CONSTANT_def_name(attr), die, pb_none);
01319 put_reference (DST_CONSTANT_def_type(attr), DW_AT_type, die);
01320 put_const_attribute (DST_CONSTANT_def_cval(attr), DW_AT_const_value, die);
01321 }
01322
01323 static void
01324 put_formal_parameter(DST_flag flag, DST_FORMAL_PARAMETER *attr, Dwarf_P_Die die)
01325 {
01326 if (DST_IS_declaration(flag)) {
01327 put_decl(DST_FORMAL_PARAMETER_decl(attr), die);
01328 put_name (DST_FORMAL_PARAMETER_name(attr), die, pb_none);
01329 put_reference (DST_FORMAL_PARAMETER_default_val(attr),
01330 DW_AT_default_value,
01331 die);
01332 put_reference (DST_FORMAL_PARAMETER_type(attr), DW_AT_type, die);
01333 put_flag (DW_AT_declaration, die);
01334 } else {
01335
01336 put_decl(DST_FORMAL_PARAMETER_decl(attr), die);
01337 put_name (DST_FORMAL_PARAMETER_name(attr), die, pb_none);
01338 put_reference (DST_FORMAL_PARAMETER_type(attr), DW_AT_type, die);
01339 put_location (DST_FORMAL_PARAMETER_st(attr), 0, flag, die, DW_AT_location);
01340 if (DST_IS_optional_parm(flag)) put_flag (DW_AT_is_optional, die);
01341 if (DST_IS_variable_parm(flag)) put_flag (DW_AT_variable_parameter, die);
01342 if (DST_IS_assumed_size(flag)) put_flag (DW_AT_MIPS_assumed_size, die);
01343 put_reference (DST_FORMAL_PARAMETER_default_val(attr),
01344 DW_AT_default_value,
01345 die);
01346 put_dopetype (DST_FORMAL_PARAMETER_dopetype(attr), flag, die);
01347 if ( ! DST_IS_FOREIGN_OBJ(DST_FORMAL_PARAMETER_abstract_origin(attr))) {
01348 put_reference(
01349 DST_FORMAL_PARAMETER_abstract_origin(attr),
01350 DW_AT_abstract_origin,
01351 die);
01352 }
01353 }
01354
01355 }
01356
01357
01358 static void
01359 put_unspecified_parameters(
01360 DST_flag flag,
01361 DST_UNSPECIFIED_PARAMETERS *attr,
01362 Dwarf_P_Die die)
01363 {
01364 put_decl(DST_UNSPECIFIED_PARAMETERS_decl(attr), die);
01365
01366 }
01367
01368
01369 static void
01370 put_basetype(DST_flag flag, DST_BASETYPE *attr, Dwarf_P_Die die)
01371 {
01372 put_name (DST_BASETYPE_name(attr), die, pb_none);
01373 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_encoding,
01374 DST_BASETYPE_encoding(attr), &dw_error);
01375 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01376 DST_BASETYPE_byte_size(attr), &dw_error);
01377 }
01378
01379
01380 static void
01381 put_const_type(DST_flag flag, DST_CONST_TYPE *attr, Dwarf_P_Die die)
01382 {
01383 put_reference (DST_CONST_TYPE_type(attr), DW_AT_type, die);
01384 }
01385
01386
01387 static void
01388 put_volatile_type(DST_flag flag, DST_VOLATILE_TYPE *attr, Dwarf_P_Die die)
01389 {
01390 put_reference (DST_VOLATILE_TYPE_type(attr), DW_AT_type, die);
01391 }
01392
01393
01394 static void
01395 put_pointer_type(DST_flag flag, DST_POINTER_TYPE *attr, Dwarf_P_Die die)
01396 {
01397 put_reference (DST_POINTER_TYPE_type(attr), DW_AT_type, die);
01398 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01399 DST_POINTER_TYPE_byte_size(attr), &dw_error);
01400 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_address_class,
01401 DST_POINTER_TYPE_address_class(attr), &dw_error);
01402 }
01403
01404
01405 static void
01406 put_reference_type(DST_flag flag, DST_REFERENCE_TYPE *attr, Dwarf_P_Die die)
01407 {
01408 put_reference (DST_REFERENCE_TYPE_type(attr), DW_AT_type, die);
01409 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01410 DST_REFERENCE_TYPE_byte_size(attr), &dw_error);
01411 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_address_class,
01412 DST_REFERENCE_TYPE_address_class(attr), &dw_error);
01413 }
01414
01415
01416 static void
01417 put_typedef (DST_flag flag, DST_TYPEDEF *attr, Dwarf_P_Die die)
01418 {
01419 put_decl(DST_TYPEDEF_decl(attr), die);
01420 put_name (DST_TYPEDEF_name(attr), die, pb_typename);
01421 put_reference (DST_TYPEDEF_type(attr), DW_AT_type, die);
01422
01423
01424
01425
01426
01427 }
01428
01429 static void
01430 put_ptr_to_member_type(DST_flag flag,
01431 DST_PTR_TO_MEMBER_TYPE *attr,
01432 Dwarf_P_Die die)
01433 {
01434 put_name(DST_PTR_TO_MEMBER_TYPE_name(attr), die, pb_typename);
01435 put_reference(DST_PTR_TO_MEMBER_TYPE_type(attr), DW_AT_type, die);
01436 put_reference(DST_PTR_TO_MEMBER_TYPE_class_type(attr),
01437 DW_AT_containing_type, die);
01438 }
01439
01440 static void
01441 put_array_type(DST_flag flag, DST_ARRAY_TYPE *attr, Dwarf_P_Die die)
01442 {
01443 put_decl(DST_ARRAY_TYPE_decl(attr), die);
01444 put_name (DST_ARRAY_TYPE_name(attr), die, pb_typename);
01445 put_reference (DST_ARRAY_TYPE_type(attr), DW_AT_type, die);
01446 if (DST_ARRAY_TYPE_byte_size(attr) != 0)
01447 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01448 DST_ARRAY_TYPE_byte_size(attr), &dw_error);
01449 if (DST_IS_declaration(flag)) put_flag (DW_AT_declaration, die);
01450 #ifdef TARG_X8664
01451 if (DST_IS_GNU_vector(flag)) put_flag (DW_AT_GNU_vector, die);
01452 #endif
01453
01454
01455
01456
01457 }
01458
01459
01460
01461
01462
01463 static void
01464 put_lower_bound (DST_flag flag, DST_SUBRANGE_TYPE *attr, Dwarf_P_Die die)
01465 {
01466 DST_bounds_t cval;
01467
01468 if (DST_IS_lb_cval(flag)) {
01469 cval = DST_SUBRANGE_TYPE_lower_cval(attr);
01470 #ifndef TARG_X8664
01471
01472
01473 switch (Dwarf_Language) {
01474 case DW_LANG_C89:
01475 case DW_LANG_C:
01476 case DW_LANG_C_plus_plus:
01477 if (cval == 0) return;
01478 break;
01479 case DW_LANG_Fortran77:
01480 case DW_LANG_Fortran90:
01481 if (cval == 1) return;
01482 break;
01483 default:
01484 break;
01485 }
01486 #endif
01487 dwarf_add_AT_signed_const (dw_dbg, die, DW_AT_lower_bound, cval, &dw_error);
01488 }
01489 else {
01490 put_reference (DST_SUBRANGE_TYPE_lower_ref(attr), DW_AT_lower_bound, die);
01491 }
01492 }
01493
01494
01495 static void
01496 put_subrange_type(DST_flag flag, DST_SUBRANGE_TYPE *attr, Dwarf_P_Die die)
01497 {
01498
01499 Dwarf_Half att ;
01500
01501 put_lower_bound (flag, attr, die);
01502
01503 att = DW_AT_upper_bound;
01504 if (DST_IS_count(flag))
01505 att = DW_AT_count;
01506
01507 if (DST_IS_ub_cval(flag)) {
01508 dwarf_add_AT_signed_const (dw_dbg, die, att,
01509 DST_SUBRANGE_TYPE_upper_cval(attr), &dw_error);
01510 }
01511 else {
01512 put_reference (DST_SUBRANGE_TYPE_upper_ref(attr), att, die);
01513 }
01514
01515
01516
01517 if (DST_IS_stride_1byte(flag))
01518 att = DW_AT_MIPS_stride_byte;
01519
01520 else if (DST_IS_stride_2byte(flag))
01521 att = DW_AT_MIPS_stride_elem;
01522
01523 else
01524 att = DW_AT_MIPS_stride;
01525
01526 put_reference (DST_SUBRANGE_TYPE_stride_ref(attr),att, die);
01527
01528 }
01529
01530
01531 static void
01532 put_structure_type(DST_flag flag, DST_STRUCTURE_TYPE *attr, Dwarf_P_Die die)
01533 {
01534 put_decl(DST_STRUCTURE_TYPE_decl(attr), die);
01535 put_name (DST_STRUCTURE_TYPE_name(attr), die, pb_typename);
01536 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01537 DST_STRUCTURE_TYPE_byte_size(attr), &dw_error);
01538 if (DST_IS_declaration(flag)) put_flag (DW_AT_declaration, die);
01539
01540
01541
01542
01543 }
01544
01545
01546 static void
01547 put_class_type(DST_flag flag, DST_CLASS_TYPE *attr, Dwarf_P_Die die)
01548 {
01549 put_decl(DST_CLASS_TYPE_decl(attr), die);
01550 put_name (DST_CLASS_TYPE_name(attr), die,
01551 DST_IS_declaration(flag) ? pb_none : pb_typename);
01552 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01553 DST_CLASS_TYPE_byte_size(attr), &dw_error);
01554 if (DST_IS_declaration(flag)) put_flag (DW_AT_declaration, die);
01555
01556
01557
01558
01559 }
01560
01561
01562 static void
01563 put_union_type(DST_flag flag, DST_UNION_TYPE *attr, Dwarf_P_Die die)
01564 {
01565 put_decl(DST_UNION_TYPE_decl(attr), die);
01566 put_name (DST_UNION_TYPE_name(attr), die, pb_typename);
01567 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01568 DST_UNION_TYPE_byte_size(attr), &dw_error);
01569 if (DST_IS_declaration(flag)) put_flag (DW_AT_declaration, die);
01570
01571
01572
01573
01574 }
01575
01576
01577 static void
01578 put_member(DST_flag flag, DST_MEMBER *attr, Dwarf_P_Die die)
01579 {
01580 Dwarf_P_Expr expr;
01581
01582 put_decl(DST_MEMBER_decl(attr), die);
01583 put_name (DST_MEMBER_name(attr), die, pb_none);
01584 put_reference (DST_MEMBER_type(attr), DW_AT_type, die);
01585 if (DST_IS_bitfield(flag)) {
01586 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01587 DST_MEMBER_byte_size(attr), &dw_error);
01588 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_bit_offset,
01589 DST_MEMBER_bit_offset(attr), &dw_error);
01590 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_bit_size,
01591 DST_MEMBER_bit_size(attr), &dw_error);
01592 }
01593 put_dopetype (DST_MEMBER_dopetype(attr), flag, die);
01594 if (DST_IS_declaration(flag)) {
01595 put_flag (DW_AT_declaration, die);
01596 }
01597 else {
01598
01599
01600
01601
01602 expr = dwarf_new_expr (dw_dbg, &dw_error);
01603 #ifdef KEY
01604
01605
01606
01607
01608 dwarf_add_expr_gen (expr, DW_OP_plus_uconst, DST_MEMBER_memb_loc(attr), 0,
01609 &dw_error);
01610 #else
01611 dwarf_add_expr_gen (expr, DW_OP_consts, DST_MEMBER_memb_loc(attr), 0,
01612 &dw_error);
01613 #endif
01614 #if pv292951
01615
01616 dwarf_add_expr_gen (expr, DW_OP_plus, 0, 0, &dw_error);
01617 #endif
01618
01619 if (expr != NULL) {
01620
01621 if (Dwarf_Language == DW_LANG_Fortran90)
01622 if (DST_IS_deref(flag))
01623 dwarf_add_expr_gen (expr, DW_OP_deref, 0, 0, &dw_error);
01624
01625 dwarf_add_AT_location_expr (dw_dbg, die,
01626 DW_AT_data_member_location, expr, &dw_error);
01627 }
01628 }
01629 #ifdef KEY
01630
01631 if (Dwarf_Language == DW_LANG_C_plus_plus &&
01632 DST_MEMBER_accessibility(attr) != 0)
01633 dwarf_add_AT_unsigned_const(dw_dbg, die, DW_AT_accessibility,
01634 DST_MEMBER_accessibility(attr), &dw_error);
01635 #endif
01636
01637 }
01638
01639
01640 static void
01641 put_template_type_param(DST_flag flag, DST_TEMPLATE_TYPE_PARAMETER *attr,
01642 Dwarf_P_Die die)
01643 {
01644 put_name (DST_TEMPLATE_TYPE_PARAMETER_name(attr), die, pb_none);
01645 put_reference (DST_TEMPLATE_TYPE_PARAMETER_type(attr), DW_AT_type, die);
01646 }
01647
01648 static void
01649 put_template_value_param(DST_flag flag, DST_TEMPLATE_VALUE_PARAMETER *attr,
01650 Dwarf_P_Die die)
01651 {
01652 put_reference (DST_TEMPLATE_VALUE_PARAMETER_type(attr), DW_AT_type, die);
01653 put_name (DST_TEMPLATE_VALUE_PARAMETER_name(attr), die, pb_none);
01654 put_const_attribute (
01655 DST_TEMPLATE_VALUE_PARAMETER_cval(attr), DW_AT_const_value, die);
01656 }
01657
01658
01659 static void
01660 put_inheritance(DST_flag flag, DST_INHERITANCE *attr, Dwarf_P_Die die)
01661 {
01662 Dwarf_P_Expr expr;
01663
01664 put_reference (DST_INHERITANCE_type(attr), DW_AT_type, die);
01665 expr = dwarf_new_expr (dw_dbg, &dw_error);
01666 #ifdef KEY
01667
01668
01669
01670
01671
01672
01673 if (DST_INHERITANCE_virtuality(attr) == DW_VIRTUALITY_none)
01674 dwarf_add_expr_gen (expr, DW_OP_plus_uconst, DST_INHERITANCE_memb_loc(attr),
01675 0, &dw_error);
01676 else {
01677
01678 dwarf_add_expr_gen (expr, DW_OP_dup, 0, 0, &dw_error);
01679 dwarf_add_expr_gen (expr, DW_OP_deref, 0, 0, &dw_error);
01680 dwarf_add_expr_gen (expr, DW_OP_lit0+DST_INHERITANCE_memb_loc(attr),
01681 0, 0, &dw_error);
01682 dwarf_add_expr_gen (expr, DW_OP_minus, 0, 0, &dw_error);
01683 dwarf_add_expr_gen (expr, DW_OP_deref, 0, 0, &dw_error);
01684 dwarf_add_expr_gen (expr, DW_OP_plus, 0, 0, &dw_error);
01685 }
01686 #else
01687 dwarf_add_expr_gen (expr, DW_OP_consts, DST_INHERITANCE_memb_loc(attr), 0,
01688 &dw_error);
01689 #endif
01690 if (expr != NULL) {
01691 dwarf_add_AT_location_expr (dw_dbg, die, DW_AT_data_member_location,
01692 expr, &dw_error);
01693 if (DST_INHERITANCE_virtuality(attr) != DW_VIRTUALITY_none)
01694 dwarf_add_AT_unsigned_const(dw_dbg, die, DW_AT_virtuality,
01695 DST_INHERITANCE_virtuality(attr),
01696 &dw_error);
01697 }
01698 #ifdef KEY
01699
01700 dwarf_add_AT_unsigned_const(dw_dbg, die, DW_AT_accessibility,
01701 DST_INHERITANCE_accessibility(attr), &dw_error);
01702 #endif
01703 }
01704
01705 static void
01706 put_enumeration_type(DST_flag flag, DST_ENUMERATION_TYPE *attr, Dwarf_P_Die die)
01707 {
01708 put_decl(DST_ENUMERATION_TYPE_decl(attr), die);
01709 put_name (DST_ENUMERATION_TYPE_name(attr), die, pb_typename);
01710 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01711 DST_ENUMERATION_TYPE_byte_size(attr), &dw_error);
01712 if (DST_IS_declaration(flag)) put_flag (DW_AT_declaration, die);
01713
01714
01715
01716
01717 }
01718
01719
01720 static void
01721 put_enumerator(DST_flag flag, DST_ENUMERATOR *attr, Dwarf_P_Die die)
01722 {
01723 put_decl(DST_ENUMERATOR_decl(attr), die);
01724 put_name (DST_ENUMERATOR_name(attr), die, pb_typename);
01725 put_const_attribute (DST_ENUMERATOR_cval(attr), DW_AT_const_value, die);
01726 }
01727
01728
01729 static void
01730 put_subroutine_type(DST_flag flag, DST_SUBROUTINE_TYPE *attr, Dwarf_P_Die die)
01731 {
01732 put_decl(DST_SUBROUTINE_TYPE_decl(attr), die);
01733 put_name (DST_SUBROUTINE_TYPE_name(attr), die, pb_typename);
01734 put_reference (DST_SUBROUTINE_TYPE_type(attr), DW_AT_type, die);
01735 if (DST_IS_prototyped(flag)) put_flag (DW_AT_prototyped, die);
01736
01737
01738
01739
01740 }
01741
01742 static void
01743 put_entry_point (DST_flag flag, DST_ENTRY_POINT *attr, Dwarf_P_Die die)
01744 {
01745 put_decl (DST_ENTRY_POINT_decl(attr), die);
01746 put_name (DST_ENTRY_POINT_name(attr), die, pb_pubname);
01747 put_reference (DST_ENTRY_POINT_type(attr), DW_AT_type, die);
01748 dwarf_add_AT_targ_address_b (dw_dbg, die, DW_AT_low_pc, 0,
01749 Cg_Dwarf_Symtab_Entry(CGD_ELFSYM,
01750 get_elfindex_from_ASSOC_INFO (DST_ENTRY_POINT_st(attr))),
01751 &dw_error);
01752 }
01753
01754 static void
01755 put_common_block (DST_flag flag, DST_COMMON_BLOCK *attr, Dwarf_P_Die die)
01756 {
01757 put_name (DST_COMMON_BLOCK_name(attr), die, pb_none);
01758 put_location (DST_COMMON_BLOCK_st(attr), 0, flag, die, DW_AT_location);
01759 }
01760
01761 static void
01762 put_common_inclusion (DST_flag flag, DST_COMMON_INCL *attr, Dwarf_P_Die die)
01763 {
01764 put_decl (DST_COMMON_INCL_decl(attr), die);
01765 put_reference (DST_COMMON_INCL_com_blk(attr), DW_AT_common_reference, die);
01766 }
01767
01768 #ifdef KEY
01769 static void
01770 put_imported_decl (DST_flag flag, DST_IMPORTED_DECL *attr, Dwarf_P_Die die)
01771 {
01772 put_name (DST_IMPORTED_DECL_name(attr), die, pb_none);
01773
01774
01775 }
01776
01777 static void
01778 put_module (DST_flag flag, DST_MODULE *attr, Dwarf_P_Die die)
01779 {
01780 put_name (DST_MODULE_name(attr), die, pb_none);
01781 put_decl (DST_MODULE_decl(attr), die);
01782 }
01783 #endif
01784
01785 static void
01786 put_string_type (DST_flag flag, DST_STRING_TYPE *attr, Dwarf_P_Die die)
01787 {
01788 DST_INFO_IDX ref_idx;
01789 DST_INFO *info;
01790 DST_VARIABLE *vattr;
01791
01792 put_decl (DST_STRING_TYPE_decl(attr), die);
01793 put_name (DST_STRING_TYPE_name(attr), die, pb_none);
01794 if (DST_IS_cval (flag)) {
01795 dwarf_add_AT_unsigned_const (dw_dbg, die, DW_AT_byte_size,
01796 DST_STRING_TYPE_len_cval(attr), &dw_error);
01797 }
01798 else {
01799
01800
01801 ref_idx = DST_STRING_TYPE_len_ref(attr);
01802 if (DST_IS_NULL(ref_idx)) return;
01803 info = DST_INFO_IDX_TO_PTR(ref_idx);
01804 vattr = DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_VARIABLE);
01805 put_location (DST_VARIABLE_def_st(vattr), 0, flag, die, DW_AT_string_length);
01806 }
01807 }
01808
01809 #ifdef KEY
01810 static void
01811 put_namelist (DST_NAMELIST *attr, Dwarf_P_Die die)
01812 {
01813 put_name (DST_NAMELIST_name(attr), die, pb_none);
01814 }
01815
01816 static void
01817 put_namelist_item (DST_NAMELIST_ITEM *attr, Dwarf_P_Die die)
01818 {
01819 put_name (DST_NAMELIST_ITEM_name(attr), die, pb_none);
01820 }
01821 #endif
01822
01823 static void
01824 Write_Attributes (
01825 DST_DW_tag tag,
01826 DST_flag flag,
01827 DST_ATTR_IDX iattr,
01828 Dwarf_P_Die die)
01829 {
01830 switch (tag) {
01831 case DW_TAG_compile_unit:
01832 put_compile_unit(DST_ATTR_IDX_TO_PTR(iattr, DST_COMPILE_UNIT), die);
01833 dwarf_add_die_to_debug (dw_dbg, die, &dw_error);
01834 break;
01835 case DW_TAG_subprogram:
01836 put_subprogram(flag,
01837 DST_ATTR_IDX_TO_PTR(iattr, DST_SUBPROGRAM),
01838 die);
01839 break;
01840 case DW_TAG_lexical_block:
01841 put_lexical_block(flag,
01842 DST_ATTR_IDX_TO_PTR(iattr, DST_LEXICAL_BLOCK),
01843 die);
01844 break;
01845 case DW_TAG_inlined_subroutine:
01846 put_inlined_subroutine(DST_ATTR_IDX_TO_PTR(iattr, DST_INLINED_SUBROUTINE),
01847 die);
01848 break;
01849 case DW_TAG_label:
01850 put_label(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_LABEL), die);
01851 break;
01852 case DW_TAG_variable:
01853 put_variable(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_VARIABLE), die);
01854 break;
01855 case DW_TAG_formal_parameter:
01856 put_formal_parameter(
01857 flag, DST_ATTR_IDX_TO_PTR(iattr, DST_FORMAL_PARAMETER), die);
01858 break;
01859 case DW_TAG_constant:
01860 put_constant( flag, DST_ATTR_IDX_TO_PTR(iattr, DST_CONSTANT), die);
01861 break;
01862 case DW_TAG_unspecified_parameters:
01863 put_unspecified_parameters(
01864 flag,
01865 DST_ATTR_IDX_TO_PTR(iattr, DST_UNSPECIFIED_PARAMETERS), die);
01866 break;
01867 case DW_TAG_base_type:
01868 put_basetype(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_BASETYPE), die);
01869 break;
01870 case DW_TAG_const_type:
01871 put_const_type(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_CONST_TYPE), die);
01872 break;
01873 case DW_TAG_volatile_type:
01874 put_volatile_type(flag,
01875 DST_ATTR_IDX_TO_PTR(iattr, DST_VOLATILE_TYPE), die);
01876 break;
01877 case DW_TAG_pointer_type:
01878 put_pointer_type(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_POINTER_TYPE), die);
01879 break;
01880 case DW_TAG_reference_type:
01881 put_reference_type(flag,
01882 DST_ATTR_IDX_TO_PTR(iattr, DST_REFERENCE_TYPE) ,die);
01883 break;
01884 case DW_TAG_typedef:
01885 put_typedef(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_TYPEDEF), die);
01886 break;
01887 case DW_TAG_ptr_to_member_type:
01888 put_ptr_to_member_type(flag,
01889 DST_ATTR_IDX_TO_PTR(iattr,
01890 DST_PTR_TO_MEMBER_TYPE),
01891 die);
01892 break;
01893 case DW_TAG_array_type:
01894 put_array_type(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_ARRAY_TYPE), die);
01895 break;
01896 case DW_TAG_subrange_type:
01897 put_subrange_type(flag,
01898 DST_ATTR_IDX_TO_PTR(iattr, DST_SUBRANGE_TYPE), die);
01899 break;
01900 case DW_TAG_structure_type:
01901 put_structure_type(flag,
01902 DST_ATTR_IDX_TO_PTR(iattr, DST_STRUCTURE_TYPE), die);
01903 break;
01904 case DW_TAG_class_type:
01905 put_class_type(flag,
01906 DST_ATTR_IDX_TO_PTR(iattr, DST_CLASS_TYPE), die);
01907 break;
01908 case DW_TAG_union_type:
01909 put_union_type(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_UNION_TYPE), die);
01910 break;
01911 case DW_TAG_member:
01912 put_member(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_MEMBER), die);
01913 break;
01914 case DW_TAG_inheritance:
01915 put_inheritance(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_INHERITANCE), die);
01916 break;
01917 case DW_TAG_template_type_param:
01918 put_template_type_param (
01919 flag,
01920 DST_ATTR_IDX_TO_PTR(iattr, DST_TEMPLATE_TYPE_PARAMETER), die);
01921 break;
01922 case DW_TAG_template_value_param:
01923 put_template_value_param (
01924 flag,
01925 DST_ATTR_IDX_TO_PTR(iattr, DST_TEMPLATE_VALUE_PARAMETER), die);
01926 break;
01927 case DW_TAG_enumeration_type:
01928 put_enumeration_type(
01929 flag,
01930 DST_ATTR_IDX_TO_PTR(iattr, DST_ENUMERATION_TYPE), die);
01931 break;
01932 case DW_TAG_enumerator:
01933 put_enumerator(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_ENUMERATOR), die);
01934 break;
01935 case DW_TAG_subroutine_type:
01936 put_subroutine_type(flag,
01937 DST_ATTR_IDX_TO_PTR(iattr, DST_SUBROUTINE_TYPE), die);
01938 break;
01939 case DW_TAG_entry_point:
01940 put_entry_point (flag,
01941 DST_ATTR_IDX_TO_PTR(iattr, DST_ENTRY_POINT), die);
01942 break;
01943 case DW_TAG_common_block:
01944 put_common_block (flag,
01945 DST_ATTR_IDX_TO_PTR(iattr, DST_COMMON_BLOCK), die);
01946 break;
01947 case DW_TAG_common_inclusion:
01948 put_common_inclusion (flag,
01949 DST_ATTR_IDX_TO_PTR(iattr, DST_COMMON_INCL), die);
01950 break;
01951 case DW_TAG_string_type:
01952 put_string_type (flag,
01953 DST_ATTR_IDX_TO_PTR(iattr, DST_STRING_TYPE), die);
01954 break;
01955 #ifdef KEY
01956
01957 case DW_TAG_namelist:
01958 put_namelist (DST_ATTR_IDX_TO_PTR(iattr, DST_NAMELIST), die);
01959 break;
01960 case DW_TAG_namelist_item:
01961 put_namelist_item (DST_ATTR_IDX_TO_PTR(iattr, DST_NAMELIST_ITEM), die);
01962 break;
01963 #ifdef KEY
01964 case DW_TAG_imported_declaration:
01965 put_imported_decl(flag,
01966 DST_ATTR_IDX_TO_PTR(iattr, DST_IMPORTED_DECL), die);
01967 break;
01968 case DW_TAG_module:
01969 put_module(flag, DST_ATTR_IDX_TO_PTR(iattr, DST_MODULE), die);
01970 break;
01971 #endif
01972 #endif
01973
01974 default:
01975 ErrMsg (EC_Unimplemented, "Write_Attributes: TAG not handled");
01976 break;
01977 }
01978 if (DST_IS_artificial(flag))
01979 put_flag(DW_AT_artificial, die);
01980 }
01981
01982
01983
01984 static void Set_Enclosing_Die (Dwarf_P_Die die, mINT32 level)
01985 {
01986
01987 if ( level >= CGD_enclosing_proc_max ) {
01988
01989 CGD_enclosing_proc_max = level + 8;
01990
01991 if ( CGD_enclosing_proc == NULL ) {
01992 CGD_enclosing_proc =
01993 (Dwarf_P_Die *) calloc( CGD_enclosing_proc_max,
01994 sizeof(*CGD_enclosing_proc) );
01995 }
01996 else {
01997 CGD_enclosing_proc =
01998 (Dwarf_P_Die *) realloc( CGD_enclosing_proc,
01999 CGD_enclosing_proc_max * sizeof(*CGD_enclosing_proc) );
02000 }
02001 }
02002 CGD_enclosing_proc[level] = die;
02003 }
02004
02005
02006
02007
02008
02009
02010
02011 static Dwarf_P_Die
02012 preorder_visit (
02013 DST_INFO_IDX idx,
02014 Dwarf_P_Die parent,
02015 Dwarf_P_Die left_sibling,
02016 INT tree_level,
02017 BOOL visit_children)
02018 {
02019 DST_INFO *info;
02020 DST_INFO_IDX child_idx;
02021 Dwarf_P_Die die;
02022 DST_DW_tag tag;
02023 DST_flag flag;
02024
02025 info = DST_INFO_IDX_TO_PTR (idx);
02026 tag = DST_INFO_tag (info);
02027 flag = DST_INFO_flag (info);
02028 die = (Dwarf_P_Die) DST_INFO_dieptr (info);
02029
02030
02031
02032
02033
02034
02035 if (die == NULL) {
02036 die = dwarf_new_die (dw_dbg, tag, parent, NULL, left_sibling, NULL,
02037 &dw_error);
02038 DST_INFO_dieptr(info) = die;
02039 if (Trace_Dwarf) {
02040 fprintf (TFile,"NEW die for [%d,%d]: %p, parent: %p, left_sibling:%p, tag:%d\n",
02041 idx.block_idx, idx.byte_idx, die, parent, left_sibling, tag);
02042 }
02043 }
02044 else {
02045 dwarf_die_link (die, parent, NULL, left_sibling, NULL, &dw_error);
02046 if (Trace_Dwarf) {
02047 fprintf (TFile,"link die for [%d,%d]: %p, parent: %p, left_sibling:%p, tag:%d\n",
02048 idx.block_idx, idx.byte_idx, die, parent, left_sibling, tag);
02049 }
02050 }
02051
02052 #ifdef KEY
02053 Current_Top_Level_Idx = idx;
02054 #endif
02055
02056 Write_Attributes (tag,
02057 flag,
02058 DST_INFO_attributes(info),
02059 die);
02060 if (tag == DW_TAG_inlined_subroutine && visit_children) {
02061
02062 ST *st;
02063 DST_INFO_IDX ref_idx = DST_INLINED_SUBROUTINE_abstract_origin(
02064 DST_ATTR_IDX_TO_PTR(
02065 DST_INFO_attributes(info), DST_INLINED_SUBROUTINE));
02066 if (!DST_IS_NULL(ref_idx) && !DST_IS_FOREIGN_OBJ (ref_idx)) {
02067 info = DST_INFO_IDX_TO_PTR (ref_idx);
02068 st = Get_ST_From_DST(DST_SUBPROGRAM_def_st(
02069 DST_ATTR_IDX_TO_PTR(
02070 DST_INFO_attributes(info), DST_SUBPROGRAM)));
02071 if (st != NULL && ST_is_not_used(st)) {
02072 visit_children = FALSE;
02073 }
02074 }
02075 }
02076
02077 if (!visit_children) return die;
02078
02079 parent = die;
02080 left_sibling = NULL;
02081 for (child_idx = DST_first_child (idx);
02082 !DST_IS_NULL(child_idx);
02083 child_idx = DST_INFO_sibling(DST_INFO_IDX_TO_PTR(child_idx)))
02084 {
02085 info = DST_INFO_IDX_TO_PTR (child_idx);
02086 #ifdef KEY
02087 if ((DST_INFO_tag(info) != DW_TAG_subprogram &&
02088 DST_INFO_tag(info) != DW_TAG_entry_point)
02089 || DST_IS_declaration(DST_INFO_flag(info)) )
02090 #else
02091 if (DST_INFO_tag(info) != DW_TAG_subprogram
02092 || DST_IS_declaration(DST_INFO_flag(info)) )
02093 #endif
02094 {
02095 left_sibling =
02096 preorder_visit (child_idx, parent, left_sibling, tree_level + 1, visit_children);
02097
02098
02099 parent = NULL;
02100 }
02101 }
02102 return die;
02103 }
02104
02105 #ifdef KEY
02106 #include <map>
02107 using namespace std;
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119 typedef map<DST_INFO *, Dwarf_P_Die> DST_INFO_map_t;
02120 static DST_INFO_map_t DST_INFO_map;
02121
02122
02123
02124
02125
02126
02127 static void
02128 build_map(DST_INFO_IDX parent_idx, Dwarf_P_Die parent_p_die)
02129 {
02130 for (DST_INFO_IDX child_idx = DST_first_child(parent_idx);
02131 !DST_IS_NULL(child_idx);
02132 child_idx = DST_INFO_sibling(DST_INFO_IDX_TO_PTR(child_idx)))
02133 {
02134 DST_INFO *child_info = DST_INFO_IDX_TO_PTR (child_idx);
02135 int tag = DST_INFO_tag(child_info);
02136 if (tag == DW_TAG_subprogram || tag == DW_TAG_entry_point) {
02137 DST_INFO_map[child_info] = parent_p_die;
02138 }
02139 }
02140 }
02141 #endif
02142
02143
02144 static void
02145 Traverse_Global_DST (void)
02146 {
02147 DST_INFO_IDX idx;
02148 DST_INFO *info;
02149 Dwarf_P_Die parent;
02150
02151 if (Trace_Dwarf) {
02152 fprintf(TFile, "Trace Global DST\n");
02153 }
02154
02155 for (idx = DST_first_child (cu_idx);
02156 !DST_IS_NULL(idx);
02157 idx = DST_INFO_sibling(DST_INFO_IDX_TO_PTR(idx)))
02158 {
02159 info = DST_INFO_IDX_TO_PTR (idx);
02160
02161 if (DST_INFO_tag(info) == DW_TAG_subprogram
02162 || DST_INFO_tag(info) == DW_TAG_entry_point)
02163 continue;
02164
02165
02166
02167
02168 parent = CGD_enclosing_proc[GLOBAL_LEVEL];
02169 #ifdef KEY
02170 Dwarf_P_Die die = preorder_visit (idx, parent, NULL, LOCAL_LEVEL,
02171 TRUE );
02172 if (DST_INFO_tag(info) == DW_TAG_module) {
02173 build_map(idx, die);
02174 }
02175 #else
02176 (void) preorder_visit (idx, parent, NULL, LOCAL_LEVEL, TRUE );
02177 #endif
02178 DST_SET_info_mark(DST_INFO_flag(info));
02179 }
02180 }
02181
02182
02183 static void
02184 Traverse_Extra_DST (void)
02185 {
02186 DST_INFO_IDX idx;
02187 DST_INFO *info;
02188 Dwarf_P_Die parent;
02189 BOOL inlined_subp;
02190 BOOL visit_children;
02191
02192 if (Trace_Dwarf) {
02193 fprintf(TFile, "Trace Extra DST\n");
02194 }
02195
02196 for (idx = DST_first_child (cu_idx);
02197 !DST_IS_NULL(idx);
02198 idx = DST_INFO_sibling(DST_INFO_IDX_TO_PTR(idx)))
02199 {
02200 info = DST_INFO_IDX_TO_PTR (idx);
02201 if (DST_IS_info_mark(DST_INFO_flag(info)))
02202 continue;
02203
02204
02205
02206
02207
02208 if (DST_INFO_tag(info) == DW_TAG_subprogram
02209 && ! DST_IS_declaration(DST_INFO_flag(info)) )
02210 {
02211 DST_SUBPROGRAM *PU_attr = DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_SUBPROGRAM);
02212 inlined_subp = subprogram_def_is_inlined(PU_attr);
02213 visit_children = FALSE;
02214 }
02215 else {
02216 visit_children = TRUE;
02217 inlined_subp = FALSE;
02218 }
02219
02220 if ((DST_INFO_tag(info) != DW_TAG_subprogram
02221 && DST_INFO_tag(info) != DW_TAG_entry_point)
02222 || DST_IS_declaration(DST_INFO_flag(info))
02223 || inlined_subp )
02224 {
02225
02226
02227
02228 parent = CGD_enclosing_proc[GLOBAL_LEVEL];
02229 (void) preorder_visit (idx, parent, NULL, LOCAL_LEVEL, visit_children);
02230 DST_SET_info_mark(DST_INFO_flag(info));
02231 }
02232 }
02233 }
02234
02235
02236
02237
02238
02239
02240
02241 static void
02242 Traverse_DST (ST *PU_st, DST_IDX pu_idx)
02243 {
02244 DST_INFO *info;
02245 DST_SUBPROGRAM *PU_attr;
02246 Dwarf_P_Die die;
02247 Dwarf_P_Die parent;
02248 INT nestlevel;
02249 DST_ASSOC_INFO assoc_info;
02250
02251 info = DST_INFO_IDX_TO_PTR (pu_idx);
02252 FmtAssert ( (DST_INFO_tag(info) == DW_TAG_subprogram)
02253 && !DST_IS_declaration(DST_INFO_flag(info)),
02254 ("Traverse_DST: pu_idx is not a subprogram def?"));
02255 PU_attr = DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_SUBPROGRAM);
02256 assoc_info = DST_SUBPROGRAM_def_st(PU_attr);
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268 FmtAssert ( (DST_ASSOC_INFO_st_level(assoc_info) == ST_level(PU_st)),
02269 ("Traverse_DST: pu_idx doesn't match PU_st"));
02270 ST *assoc_st = Get_ST_From_DST (assoc_info);
02271 BOOL is_ext_inline = PU_is_extern_inline (Pu_Table[ST_pu(assoc_st)]);
02272 char *assoc_pu_name = ST_name(Get_ST_From_DST (assoc_info));
02273
02274 FmtAssert ( (is_ext_inline && !strcmp(assoc_pu_name, ST_name(PU_st))) ||
02275 (DST_ASSOC_INFO_st_index(assoc_info) == ST_index(PU_st)),
02276 ("Traverse_DST: pu_idx doesn't match PU_st"));
02277
02278 if (Trace_Dwarf)
02279 fprintf ( TFile, "Traverse_DST: found idx [%d,%d] for %s\n",
02280 pu_idx.block_idx, pu_idx.byte_idx, ST_name(PU_st));
02281
02282 DST_SET_info_mark(DST_INFO_flag(info));
02283
02284
02285 nestlevel = CURRENT_SYMTAB - 1;
02286 parent = CGD_enclosing_proc[nestlevel-1];
02287 #ifdef KEY
02288
02289 if (DST_INFO_map.find(info) != DST_INFO_map.end()) {
02290 parent = DST_INFO_map[info];
02291 }
02292 #endif
02293 die = preorder_visit (pu_idx, parent, NULL, nestlevel, TRUE );
02294 Set_Enclosing_Die (die, nestlevel);
02295
02296 if (PU_has_altentry(Get_Current_PU())) {
02297
02298 DST_INFO_IDX idx;
02299 idx = DST_INFO_sibling(DST_INFO_IDX_TO_PTR(pu_idx));
02300 while ( !DST_IS_NULL(idx) ) {
02301 info = DST_INFO_IDX_TO_PTR(idx);
02302
02303
02304
02305
02306
02307 if ( ! (DST_INFO_tag(info) == DW_TAG_entry_point
02308 || DST_INFO_tag(info) == DW_TAG_base_type
02309 || DST_INFO_tag(info) == DW_TAG_subroutine_type
02310 || (DST_INFO_tag(info) == DW_TAG_subprogram
02311 && DST_IS_declaration(DST_INFO_flag(info)) ) ))
02312 {
02313 break;
02314 }
02315 if ( ! DST_IS_info_mark(DST_INFO_flag(info))) {
02316 DST_SET_info_mark(DST_INFO_flag(info));
02317 die = preorder_visit (idx, NULL, die , nestlevel, TRUE);
02318 }
02319 idx = DST_INFO_sibling(info);
02320 }
02321 }
02322 }
02323
02324
02325 void
02326 Cg_Dwarf_Process_PU (Elf64_Word scn_index,
02327 LABEL_IDX begin_label,
02328 LABEL_IDX end_label,
02329 #ifdef TARG_X8664
02330 LABEL_IDX *eh_pushbp_label,
02331 LABEL_IDX *eh_movespbp_label,
02332 LABEL_IDX *eh_adjustsp_label,
02333 LABEL_IDX *eh_callee_saved_reg,
02334 LABEL_IDX *first_bb_labels,
02335 LABEL_IDX *last_bb_labels,
02336 INT32 pu_entries,
02337 #endif
02338 INT32 end_offset,
02339 ST *PU_st,
02340 DST_IDX pu_dst,
02341 Elf64_Word eh_index,
02342 INT eh_offset,
02343
02344
02345
02346 INT low_pc,
02347 INT high_pc)
02348 {
02349 DST_INFO *info;
02350 Dwarf_P_Die PU_die;
02351 Dwarf_P_Expr expr;
02352 Dwarf_P_Fde fde;
02353 #ifdef TARG_X8664
02354 Dwarf_P_Fde eh_fde = 0;
02355 #endif
02356 DST_SUBPROGRAM *PU_attr;
02357 static BOOL processed_globals = FALSE;
02358
02359 cur_text_index = scn_index;
02360 Trace_Dwarf = Get_Trace ( TP_EMIT, 8 );
02361
02362
02363 if (Disable_DST) return;
02364
02365 if ( ! processed_globals) {
02366
02367
02368
02369 Traverse_Global_DST ();
02370 processed_globals = TRUE;
02371 }
02372
02373 if (Trace_Dwarf)
02374 fprintf(TFile, "dwarf for %s:\n", ST_name(PU_st));
02375
02376 if (DST_IS_NULL(pu_dst)) {
02377
02378 if (strncmp(ST_name(PU_st), "*clone*", 7) != 0)
02379 DevWarn("NULL DST passed to CG for %s", ST_name(PU_st));
02380 return;
02381 }
02382 Traverse_DST (PU_st, pu_dst);
02383
02384 if (DST_IS_NULL(pu_dst)) return;
02385
02386 info = DST_INFO_IDX_TO_PTR (pu_dst);
02387
02388 if (DST_INFO_tag(info) != DW_TAG_subprogram) return;
02389
02390 PU_attr = DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_SUBPROGRAM);
02391 PU_die = (Dwarf_P_Die) DST_INFO_dieptr(info);
02392
02393 if (subprogram_def_is_inlined(PU_attr)) {
02394
02395
02396
02397 Dwarf_P_Die idie = dwarf_new_die (dw_dbg, DW_TAG_subprogram, NULL, NULL, PU_die, NULL, &dw_error);
02398 if (Trace_Dwarf) {
02399 fprintf (TFile,"NEW subprogram concrete instance: die: %p, left_sibling:%p\n",
02400 idie, PU_die);
02401 }
02402
02403
02404 put_concrete_subprogram(pu_dst,
02405 0 ,
02406 0 ,
02407 idie);
02408 PU_die = idie;
02409 }
02410
02411
02412 expr = dwarf_new_expr (dw_dbg, &dw_error);
02413 #ifndef TARG_X8664
02414 #ifndef TARG_NVISA
02415 if (Current_PU_Stack_Model != SMODEL_SMALL)
02416 dwarf_add_expr_gen (expr, DW_OP_bregx,
02417 REGISTER_machine_id (TN_register_class(FP_TN), TN_register(FP_TN)),
02418 0, &dw_error);
02419 else
02420 dwarf_add_expr_gen (expr, DW_OP_bregx,
02421 REGISTER_machine_id (TN_register_class(SP_TN), TN_register(SP_TN)),
02422 Frame_Len, &dw_error);
02423 #endif
02424 #else
02425
02426 if (Current_PU_Stack_Model != SMODEL_SMALL)
02427 dwarf_add_expr_gen (expr,
02428 Is_Target_64bit() ? DW_OP_reg6 : DW_OP_reg5,
02429 0, 0, &dw_error) ;
02430 else
02431 dwarf_add_expr_gen (expr,
02432 Is_Target_64bit() ? DW_OP_breg7 : DW_OP_breg4,
02433 Frame_Len, 0, &dw_error) ;
02434 #if 0
02435
02436
02437
02438
02439 if (Current_PU_Stack_Model != SMODEL_SMALL)
02440 dwarf_add_expr_gen (expr, DW_OP_bregx,
02441 6 ,
02442 0, &dw_error);
02443 else
02444 dwarf_add_expr_gen (expr, DW_OP_bregx,
02445 7 ,
02446 Frame_Len, &dw_error);
02447 #endif
02448 #endif
02449
02450 dwarf_add_AT_location_expr(dw_dbg, PU_die, DW_AT_frame_base, expr, &dw_error);
02451 if (PU_is_mainpu(ST_pu(PU_st))) {
02452 dwarf_add_AT_unsigned_const (dw_dbg, PU_die, DW_AT_calling_convention,
02453 DW_CC_program, &dw_error);
02454 }
02455
02456 Dwarf_Unsigned begin_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02457 begin_label,
02458 scn_index);
02459 Dwarf_Unsigned end_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02460 end_label,
02461 scn_index);
02462
02463 #ifndef TARG_X8664
02464 fde = Build_Fde_For_Proc (dw_dbg, REGION_First_BB,
02465 begin_entry,
02466 end_entry,
02467 end_offset,
02468 low_pc, high_pc);
02469 #else
02470 Dwarf_Unsigned pushbp_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02471 eh_pushbp_label[0],
02472 scn_index);
02473 Dwarf_Unsigned movespbp_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02474 eh_movespbp_label[0],
02475 scn_index);
02476 Dwarf_Unsigned adjustsp_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02477 eh_adjustsp_label[0],
02478 scn_index);
02479 Dwarf_Unsigned callee_saved_reg;
02480 INT num_callee_saved_regs;
02481 if (num_callee_saved_regs = Cgdwarf_Num_Callee_Saved_Regs())
02482 callee_saved_reg = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02483 eh_callee_saved_reg[0],
02484 scn_index);
02485 fde = Build_Fde_For_Proc (dw_dbg, REGION_First_BB,
02486 begin_entry,
02487 end_entry,
02488 pushbp_entry,
02489 movespbp_entry,
02490 adjustsp_entry,
02491 callee_saved_reg,
02492 end_offset,
02493 low_pc, high_pc);
02494
02495
02496 if (Dwarf_Language == DW_LANG_C_plus_plus || DEBUG_Emit_Ehframe)
02497 eh_fde = Build_Fde_For_Proc (dw_dbg, REGION_First_BB,
02498 begin_entry,
02499 end_entry,
02500 pushbp_entry,
02501 movespbp_entry,
02502 adjustsp_entry,
02503 callee_saved_reg,
02504 end_offset,
02505 low_pc, high_pc);
02506 #endif // TARG_X8664
02507
02508 Dwarf_Unsigned eh_handle;
02509
02510 if (eh_offset != DW_DLX_NO_EH_OFFSET) {
02511 eh_handle = Cg_Dwarf_Symtab_Entry(CGD_ELFSYM, eh_index);
02512 }
02513 else {
02514 eh_handle = eh_index;
02515 }
02516
02517 Em_Dwarf_Process_PU (begin_entry,
02518 end_entry,
02519 0,
02520 end_offset,
02521 PU_die,
02522 fde,
02523 #ifdef TARG_X8664
02524 eh_fde,
02525 #endif
02526 eh_handle,
02527 eh_offset);
02528 #ifdef TARG_X8664
02529 if (pu_entries > 1) {
02530 FmtAssert(Dwarf_Language == DW_LANG_Fortran77 ||
02531 Dwarf_Language == DW_LANG_Fortran90,
02532 ("Dwarf handler: > 1 PU entry in a non-Fortran language"));
02533 for (INT pu_entry = 1; pu_entry <= pu_entries; pu_entry ++) {
02534 begin_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02535 first_bb_labels[pu_entry],
02536 scn_index);
02537 end_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02538 last_bb_labels[pu_entry],
02539 scn_index);
02540 pushbp_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02541 eh_pushbp_label[pu_entry],
02542 scn_index);
02543 movespbp_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02544 eh_movespbp_label[pu_entry],
02545 scn_index);
02546 adjustsp_entry = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02547 eh_adjustsp_label[pu_entry],
02548 scn_index);
02549 if (num_callee_saved_regs = Cgdwarf_Num_Callee_Saved_Regs())
02550 callee_saved_reg = Cg_Dwarf_Symtab_Entry(CGD_LABIDX,
02551 eh_callee_saved_reg[pu_entry],
02552 scn_index);
02553 fde = Build_Fde_For_Proc (dw_dbg, REGION_First_BB,
02554 begin_entry,
02555 end_entry,
02556 pushbp_entry,
02557 movespbp_entry,
02558 adjustsp_entry,
02559 callee_saved_reg,
02560 end_offset,
02561 low_pc, high_pc);
02562 Em_Dwarf_Add_PU_Entries (begin_entry,
02563 end_entry,
02564 0,
02565 end_offset,
02566 PU_die,
02567 fde);
02568 }
02569 }
02570 #endif
02571
02572 }
02573
02574 static DST_language
02575 Get_Dwarf_Language (DST_INFO *cu_info)
02576 {
02577 return DST_COMPILE_UNIT_language( DST_ATTR_IDX_TO_PTR(
02578 DST_INFO_attributes(cu_info), DST_COMPILE_UNIT));
02579 }
02580
02581
02582
02583
02584 void
02585 Cg_Dwarf_Begin (BOOL is_64bit)
02586 {
02587 DST_INFO * cu_info;
02588 Dwarf_P_Die cu_die;
02589
02590 Trace_Dwarf = Get_Trace ( TP_EMIT, 8 );
02591 Disable_DST = Get_Trace ( TP_EMIT, 0x200 );
02592
02593 cu_idx = DST_get_compile_unit ();
02594 cu_info = DST_INFO_IDX_TO_PTR (cu_idx);
02595 Dwarf_Language = Get_Dwarf_Language (cu_info);
02596
02597 #ifdef KEY
02598 if (!CG_emit_unwind_info)
02599 dw_dbg = Em_Dwarf_Begin(is_64bit, Trace_Dwarf,
02600 0,
02601 Cg_Dwarf_Enter_Elfsym);
02602 else
02603 #endif
02604 dw_dbg = Em_Dwarf_Begin(is_64bit, Trace_Dwarf,
02605 (Dwarf_Language == DW_LANG_C_plus_plus),
02606 Cg_Dwarf_Enter_Elfsym);
02607
02608
02609 cu_die = get_ref_die (cu_idx);
02610 Set_Enclosing_Die (cu_die, GLOBAL_LEVEL);
02611 Write_Attributes (DST_INFO_tag(cu_info),
02612 DST_INFO_flag (cu_info),
02613 DST_INFO_attributes(cu_info),
02614 cu_die);
02615
02616
02617 CGD_Symtab.push_back(CGD_SYMTAB_ENTRY(CGD_ELFSYM, (Dwarf_Unsigned) -1));
02618 }
02619
02620
02621
02622
02623
02624 void Cg_Dwarf_Finish (pSCNINFO text_scninfo)
02625 {
02626 if (Disable_DST) return;
02627 Traverse_Extra_DST();
02628 }
02629
02630 typedef struct {
02631 const char *path_name;
02632 BOOL already_processed;
02633 } include_info;
02634
02635 typedef struct {
02636 const char *filename;
02637 INT incl_index;
02638 FILE *fileptr;
02639 INT max_line_printed;
02640 BOOL already_processed;
02641 Dwarf_Unsigned mod_time;
02642 Dwarf_Unsigned file_size;
02643 } file_info;
02644
02645 static file_info *file_table;
02646 static include_info *incl_table;
02647 static INT cur_file_index = 0;
02648
02649 void Cg_Dwarf_Gen_Asm_File_Table (void)
02650 {
02651 INT count;
02652 DST_IDX idx;
02653 DST_INCLUDE_DIR *incl;
02654 DST_FILE_NAME *file;
02655 const char *name;
02656 INT incl_table_size;
02657 INT file_table_size;
02658 INT new_size;
02659
02660 incl_table_size = 0;
02661 incl_table = NULL;
02662 file_table_size = 0;
02663 file_table = NULL;
02664 count = 1;
02665 for (idx = DST_get_include_dirs ();
02666 !DST_IS_NULL(idx);
02667 idx = DST_INCLUDE_DIR_next(incl))
02668 {
02669 incl = DST_DIR_IDX_TO_PTR (idx);
02670 name = DST_STR_IDX_TO_PTR (DST_INCLUDE_DIR_path(incl));
02671 if (count >= incl_table_size) {
02672 new_size = count + 10;
02673 if (incl_table == NULL)
02674 incl_table = (include_info *) malloc (new_size * sizeof (include_info));
02675 else
02676 incl_table = (include_info *) realloc (incl_table, new_size * sizeof (include_info));
02677 if (incl_table == NULL) ErrMsg (EC_No_Mem, "Cg_Dwarf_Gen_Asm_File_Table");
02678 incl_table_size = new_size;
02679 }
02680 incl_table[count].path_name = name;
02681 incl_table[count].already_processed = FALSE;
02682 count++;
02683 }
02684
02685 count = 1;
02686 for (idx = DST_get_file_names ();
02687 !DST_IS_NULL(idx);
02688 idx = DST_FILE_NAME_next(file))
02689 {
02690 file = DST_FILE_IDX_TO_PTR (idx);
02691 if (DST_IS_NULL(DST_FILE_NAME_name(file))) {
02692 name = "NULLNAME";
02693 }
02694 else {
02695 name = DST_STR_IDX_TO_PTR (DST_FILE_NAME_name(file));
02696 }
02697 if (count >= file_table_size) {
02698 new_size = count + 10;
02699 if (file_table == NULL)
02700 file_table = (file_info *) malloc (new_size * sizeof (file_info));
02701 else
02702 file_table = (file_info *) realloc (file_table,
02703 new_size * sizeof (file_info));
02704 if (file_table == NULL) ErrMsg (EC_No_Mem, "Cg_Dwarf_Gen_Asm_File_Table");
02705 file_table_size = new_size;
02706 }
02707 file_table[count].filename = name;
02708 file_table[count].incl_index = DST_FILE_NAME_dir(file);
02709 file_table[count].fileptr = NULL;
02710 file_table[count].max_line_printed = 0;
02711 file_table[count].already_processed = FALSE;
02712 file_table[count].mod_time = DST_FILE_NAME_modt(file);
02713 file_table[count].file_size = DST_FILE_NAME_size(file);
02714 count++;
02715
02716 #ifdef TEMPORARY_STABS_FOR_GDB
02717
02718 if (Debug_Level > 0 && count == 3) {
02719 fprintf(Asm_File, ".stabs \"%s/\",100,0,0,.Ltext0\n",
02720 incl_table[DST_FILE_NAME_dir(file)].path_name);
02721 fprintf(Asm_File, ".stabs \"%s\",100,0,0,.Ltext0\n", name);
02722 }
02723 #endif
02724
02725 }
02726
02727 }
02728
02729 #ifdef KEY
02730 void Cg_Dwarf_Gen_Macinfo (void)
02731 {
02732 DST_IDX idx;
02733 DST_MACR *macr;
02734 char *macro, *macname, *macvalue;
02735 INT fileindex, linenumber;
02736 BOOL processed_start_file = FALSE;
02737 BOOL processed_end_file = FALSE;
02738
02739 for (idx = DST_get_macro_info();
02740 !DST_IS_NULL(idx);
02741 idx = DST_MACR_next(macr)) {
02742 macr = DST_MACR_IDX_TO_PTR(idx);
02743 switch (DST_MACR_tag(macr)) {
02744 case DW_MACINFO_define:
02745 if (!processed_start_file) {
02746 dwarf_start_macro_file(dw_dbg,
02747 1 , 0 , &dw_error);
02748 processed_start_file = TRUE;
02749 }
02750 macro = DST_STR_IDX_TO_PTR(DST_MACR_macro(macr));
02751 dwarf_def_macro(dw_dbg, DST_MACR_lineno(macr),
02752 macro, NULL, &dw_error);
02753 break;
02754 case DW_MACINFO_undef:
02755 if (!processed_start_file) {
02756 dwarf_start_macro_file(dw_dbg,
02757 1 , 0 , &dw_error);
02758 processed_start_file = TRUE;
02759 }
02760 macname = DST_STR_IDX_TO_PTR(DST_MACR_macro(macr));
02761 macvalue = dwarf_find_macro_value_start(macname);
02762 macname[strlen(macname) - strlen(macvalue) - 1] = '\0';
02763 dwarf_undef_macro(dw_dbg, DST_MACR_lineno(macr),
02764 macname, &dw_error);
02765 break;
02766 case DW_MACINFO_start_file:
02767 fileindex = DST_MACR_fileno(macr);
02768 linenumber = DST_MACR_lineno(macr);
02769 dwarf_start_macro_file(dw_dbg, fileindex, linenumber, &dw_error);
02770 processed_start_file = TRUE;
02771 break;
02772 case DW_MACINFO_end_file:
02773 dwarf_end_macro_file(dw_dbg, &dw_error);
02774 processed_end_file = TRUE;
02775 break;
02776 default:
02777 break;
02778 }
02779 }
02780 if (processed_start_file && !processed_end_file)
02781
02782 dwarf_end_macro_file(dw_dbg, &dw_error);
02783 }
02784
02785 void
02786 Print_Directives_For_All_Files(void) {
02787 DST_IDX idx;
02788 DST_FILE_NAME *file;
02789 INT count = 1;
02790 #if ! defined(BUILD_OS_DARWIN)
02791 for (idx = DST_get_file_names();
02792 !DST_IS_NULL(idx);
02793 idx = DST_FILE_NAME_next(file)) {
02794 file = DST_FILE_IDX_TO_PTR(idx);
02795 #ifdef TARG_NVISA
02796
02797 if (strcmp(incl_table[file_table[count].incl_index].path_name, ".") == 0) {
02798 fprintf(Asm_File, "\t%s\t%d\t\"%s\"\n", AS_FILE, count,
02799 file_table[count].filename);
02800 count++;
02801 continue;
02802 }
02803 #elif defined(TARG_SL)
02804
02805
02806
02807
02808 if (file_table[count].incl_index == 0)
02809 fprintf(Asm_File, "\t%s\t%d\t\"%s\"\n", AS_FILE, count,
02810 file_table[count].filename);
02811 else
02812 #endif
02813 fprintf(Asm_File, "\t%s\t%d\t\"%s/%s\"\n", AS_FILE, count,
02814 incl_table[file_table[count].incl_index].path_name,
02815 file_table[count].filename);
02816 count++;
02817 }
02818 fputc ('\n', Asm_File);
02819 #endif
02820 }
02821 #endif
02822
02823
02824 static void
02825 print_source (SRCPOS srcpos)
02826 {
02827 USRCPOS usrcpos;
02828 char srcfile[1024];
02829 char text[1024];
02830 file_info *cur_file;
02831 INT i;
02832 INT newmax;
02833
02834 USRCPOS_srcpos(usrcpos) = srcpos;
02835
02836
02837 if (USRCPOS_filenum(usrcpos) == 0) return;
02838
02839 cur_file = &file_table[USRCPOS_filenum(usrcpos)];
02840 if (USRCPOS_filenum(usrcpos) != cur_file_index) {
02841 if (cur_file_index != 0) {
02842
02843 file_info *prev_file = &file_table[cur_file_index];
02844 fclose (prev_file->fileptr);
02845 prev_file->fileptr = NULL;
02846 }
02847 cur_file_index = USRCPOS_filenum(usrcpos);
02848 cur_file = &file_table[cur_file_index];
02849
02850 #ifdef TARG_SL
02851 if (cur_file->incl_index == 0)
02852 sprintf (srcfile, "%s",cur_file->filename);
02853 else
02854 #endif
02855 sprintf (srcfile, "%s/%s", incl_table[cur_file->incl_index].path_name,
02856 cur_file->filename);
02857 cur_file->fileptr = fopen (srcfile, "r");
02858 if (cur_file->fileptr == NULL) {
02859 cur_file_index = 0;
02860 return;
02861 }
02862 for (i = 0; i < cur_file->max_line_printed; i++) {
02863 fgets (text, sizeof(text), cur_file->fileptr);
02864 }
02865 }
02866 newmax = USRCPOS_linenum(usrcpos) - 5;
02867 if (cur_file->max_line_printed < newmax) {
02868 for (i = cur_file->max_line_printed; i < newmax; i++) {
02869 fgets (text, sizeof(text), cur_file->fileptr);
02870 }
02871 cur_file->max_line_printed = newmax;
02872 }
02873 if (cur_file->max_line_printed < USRCPOS_linenum(usrcpos)) {
02874 for (i = cur_file->max_line_printed; i < USRCPOS_linenum(usrcpos); i++) {
02875 if (fgets (text, sizeof(text), cur_file->fileptr) != NULL) {
02876
02877 if (strlen(text) >= 1023) text[1022] = '\n';
02878 #if defined(TARG_SL)
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888 if (text[strlen(text)-1] != '\n') {
02889 text[strlen(text)+1] = '\0';
02890 text[strlen(text)] = '\n';
02891 }
02892 #endif
02893 fprintf (Asm_File, "%s%4d %s", ASM_CMNT_LINE, i+1, text);
02894 }
02895 }
02896 cur_file->max_line_printed = USRCPOS_linenum(usrcpos);
02897 }
02898 }
02899
02900 #ifdef KEY
02901 BOOL Cg_Dwarf_First_Op_After_Preamble_End = FALSE;
02902 BOOL Cg_Dwarf_BB_First_Op = FALSE;
02903 #endif
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919 void
02920 Cg_Dwarf_Add_Line_Entry (INT code_address, SRCPOS srcpos)
02921 {
02922 static SRCPOS last_srcpos = 0;
02923 USRCPOS usrcpos;
02924
02925 if (srcpos == 0 && last_srcpos == 0)
02926 DevWarn("no valid srcpos at PC %d\n", code_address);
02927 #ifndef KEY
02928 if (srcpos == 0 || srcpos == last_srcpos) return;
02929 #else
02930 if (srcpos == 0 ||
02931 (!Cg_Dwarf_First_Op_After_Preamble_End && !Cg_Dwarf_BB_First_Op &&
02932 srcpos == last_srcpos))
02933 return;
02934 #endif
02935
02936 #ifdef TARG_IA64
02937
02938
02939
02940
02941
02942 if ((code_address % INST_BYTES) != 0) {
02943 #if defined(BUILD_OS_DARWIN)
02944 return;
02945 #else
02946 if (Object_Code) return;
02947 #endif
02948 }
02949 #endif
02950
02951 USRCPOS_srcpos(usrcpos) = srcpos;
02952
02953
02954
02955 USRCPOS last_usrcpos;
02956 USRCPOS_srcpos(last_usrcpos) = last_srcpos;
02957 if (USRCPOS_filenum(last_usrcpos) != USRCPOS_filenum(usrcpos)) {
02958 INT file_idx = USRCPOS_filenum(usrcpos);
02959 INT include_idx;
02960
02961 if (! file_table[file_idx].already_processed) {
02962
02963
02964 include_idx = file_table[file_idx].incl_index;
02965 if (
02966 #ifdef TARG_SL
02967 (include_idx != 0) &&
02968 #endif
02969 ! incl_table[include_idx].already_processed) {
02970
02971 #if defined(BUILD_OS_DARWIN)
02972
02973 if (1)
02974 #else
02975 if (Object_Code)
02976 #endif
02977 {
02978 Em_Dwarf_Add_Include (include_idx,
02979 incl_table[include_idx].path_name);
02980 }
02981 incl_table[include_idx].already_processed = TRUE;
02982 }
02983 #if defined(BUILD_OS_DARWIN)
02984
02985 if (1) {
02986 #else
02987 if (Object_Code) {
02988 #endif
02989 Em_Dwarf_Add_File (file_idx,
02990 file_table[file_idx].filename,
02991 include_idx,
02992 file_table[file_idx].mod_time,
02993 file_table[file_idx].file_size);
02994 }
02995 file_table[file_idx].already_processed = TRUE;
02996 #if defined(IRIX)
02997
02998
02999 if (Assembly) {
03000 CGEMIT_Prn_File_Dir_In_Asm(usrcpos,
03001 incl_table[include_idx].path_name,
03002 file_table[file_idx].filename);
03003 }
03004 #endif
03005 }
03006 #ifdef linux
03007 #ifndef KEY // skip here because already generated at beginning
03008
03009
03010
03011 if (Assembly) {
03012 include_idx = file_table[file_idx].incl_index;
03013 #ifdef TARG_SL
03014 if (include_idx == 0)
03015 CGEMIT_Prn_File_Dir_In_Asm(usrcpos,
03016 NULL,
03017 file_table[file_idx].filename);
03018 else
03019 #endif
03020 CGEMIT_Prn_File_Dir_In_Asm(usrcpos,
03021 incl_table[include_idx].path_name,
03022 file_table[file_idx].filename);
03023 }
03024 #endif
03025 #endif
03026 }
03027
03028
03029 #if defined(BUILD_OS_DARWIN)
03030
03031 if (1) {
03032 #else
03033 if (Object_Code) {
03034 #endif
03035 Em_Dwarf_Add_Line_Entry (code_address, srcpos);
03036 }
03037 if (Assembly) {
03038 CGEMIT_Prn_Line_Dir_In_Asm(usrcpos);
03039 if (List_Source)
03040 print_source (srcpos);
03041 }
03042 last_srcpos = srcpos;
03043 }
03044
03045 static inline Elf64_Word
03046 reloc_offset(char *reloc, BOOL is_64bit)
03047 {
03048 if (is_64bit) {
03049 #ifdef TARG_IA64
03050 return REL_offset(*((Elf64_AltRel *) reloc));
03051 #else
03052 return REL_offset(*((Elf64_Rel *) reloc));
03053 #endif
03054 }
03055 else {
03056 return REL32_offset(*((Elf32_Rel *) reloc));
03057 }
03058 }
03059
03060 static inline Elf64_Word
03061 reloc_sym_index(char *reloc, BOOL is_64bit)
03062 {
03063 if (is_64bit) {
03064 return REL64_sym(*((Elf64_AltRel *) reloc));
03065 }
03066 else {
03067 return REL32_sym(*((Elf32_Rel *) reloc));
03068 }
03069 }
03070
03071 static void check_reloc_fmt_and_size(Elf64_Word reloc_scn_type,
03072 Dwarf_Ptr reloc_buffer,
03073 Dwarf_Unsigned reloc_buffer_size,
03074 Dwarf_Unsigned scn_buffer_size)
03075 {
03076 }
03077
03078 #ifdef linux
03079 struct UINT32_unaligned {
03080 UINT32 val;
03081 } __attribute__ ((aligned(1)));
03082
03083 struct UINT64_unaligned {
03084 UINT64 val;
03085 } __attribute__ ((aligned(1)));
03086 #else
03087 #pragma pack(1)
03088 struct UINT32_unaligned {
03089 UINT32 val;
03090 };
03091
03092 struct UINT64_unaligned {
03093 UINT64 val;
03094 };
03095 #pragma pack(0)
03096 #endif
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109 namespace {
03110
03111
03112
03113
03114
03115 struct scn_handle {
03116 Dwarf_Unsigned sc_bufsize;
03117 Dwarf_Signed sc_scndx;
03118 Dwarf_Ptr sc_buffer;
03119 pSCNINFO sc_cursection;
03120 BOOL sc_output;
03121 };
03122
03123 struct virtual_section_position {
03124 Dwarf_Unsigned vsp_virtpos;
03125
03126
03127
03128
03129
03130
03131
03132
03133 Dwarf_Unsigned vsp_curbufpos;
03134
03135
03136 Dwarf_Signed vsp_remaining_buffercount;
03137
03138
03139 scn_handle ** vsp_buffers;
03140
03141
03142
03143 virtual_section_position(Dwarf_Signed ct,scn_handle **buffers):
03144
03145 vsp_virtpos(0),vsp_curbufpos(0),
03146 vsp_remaining_buffercount(ct),
03147 vsp_buffers(buffers) {}
03148
03149 ~virtual_section_position() {}
03150
03151
03152 Dwarf_Unsigned vsp_get_bytes(Dwarf_Unsigned offset, int size)
03153 {
03154
03155
03156
03157 FmtAssert((vsp_virtpos == offset),
03158 ("Error in vsp location (dwarf output)"));
03159
03160 if(vsp_curbufpos >= vsp_buffers[0]->sc_bufsize) {
03161
03162
03163
03164 if(vsp_remaining_buffercount < 2) {
03165 Fail_FmtAssertion("Ran off end of vsp buffer generating dwarf");
03166 }
03167
03168 --vsp_remaining_buffercount;
03169
03170 vsp_buffers++;
03171 vsp_curbufpos = 0;
03172 }
03173
03174 if((vsp_curbufpos + size) > vsp_buffers[0]->sc_bufsize) {
03175
03176 Fail_FmtAssertion("Impossible vsp buffer configuration");
03177 }
03178 Dwarf_Unsigned value;
03179 char *loc = ((char *)vsp_buffers[0]->sc_buffer) + vsp_curbufpos;
03180
03181 switch(size) {
03182 case 1:
03183 value = loc[0];
03184 break;
03185 #ifdef TARG_IA64
03186 case 4:
03187 UINT32 buf32;
03188 memcpy(&buf32, loc, sizeof(buf32));
03189 value = buf32;
03190 break;
03191 case 8:
03192 UINT64 buf64;
03193 memcpy(&buf64, loc, sizeof(buf64));
03194 value = buf64;
03195 break;
03196 #else
03197 case 4:
03198 value = ((UINT32_unaligned *)loc)->val;
03199 break;
03200 case 8:
03201 value = ((UINT64_unaligned *)loc)->val;
03202 break;
03203 #endif
03204 default:
03205 Fail_FmtAssertion("Impossible vsp buffer vsp_get_bytes size %d",
03206 (int)size);
03207 }
03208 vsp_curbufpos += size;
03209 vsp_virtpos += size;
03210
03211 return value;
03212 }
03213 Dwarf_Unsigned vsp_print_bytes(
03214 FILE * asm_file,
03215 Dwarf_Unsigned current_reloc_target,
03216 Dwarf_Unsigned cur_byte_in);
03217
03218 };
03219 }
03220
03221
03222
03223
03224 Dwarf_Unsigned
03225 virtual_section_position::vsp_print_bytes(
03226 FILE * asm_file,
03227 Dwarf_Unsigned cur_reloc_target,
03228 Dwarf_Unsigned cur_byte_in)
03229 {
03230
03231 #ifdef TARG_IA64
03232 const int bytes_per_line = 8;
03233 Dwarf_Unsigned cur_byte = cur_byte_in;
03234 int nlines_this_reloc = (cur_reloc_target - cur_byte) / bytes_per_line;
03235
03236 int i;
03237 for (i = 0; i < nlines_this_reloc; ++i) {
03238 fprintf(asm_file, "\t%s\t", AS_BYTE);
03239 int j;
03240 for (j = 1; j < bytes_per_line; ++j) {
03241 fprintf(asm_file, "0x%02x, ",
03242 (int)vsp_get_bytes(cur_byte,1));
03243 ++cur_byte;
03244 }
03245 fprintf(asm_file, "0x%02x\n",
03246 (int)vsp_get_bytes(cur_byte,1));
03247 ++cur_byte;
03248 }
03249 if (cur_byte != cur_reloc_target) {
03250 fprintf(asm_file, "\t%s\t", AS_BYTE);
03251 for (; cur_byte != cur_reloc_target - 1; ) {
03252 fprintf(asm_file, "0x%02x, ",
03253 (int)vsp_get_bytes(cur_byte,1));
03254 ++cur_byte;
03255 }
03256 fprintf(asm_file, "0x%02x\n",
03257 (int)vsp_get_bytes(cur_byte,1));
03258 ++cur_byte;
03259 }
03260 #else
03261 Dwarf_Unsigned cur_byte = cur_byte_in;
03262
03263
03264
03265
03266
03267
03268
03269
03270 const int bytes_per_word_line = 16;
03271 const int bytes_per_byte_line = 8;
03272 int i, nlines_this_reloc;
03273
03274
03275 nlines_this_reloc = (cur_reloc_target - cur_byte) / bytes_per_word_line;
03276 for (i = 0; i < nlines_this_reloc; i++) {
03277
03278 fputs("\t" AS_WORD_UNALIGNED "\t", asm_file);
03279
03280 int j;
03281 for (j = 0; j < bytes_per_word_line; j += 4) {
03282 UINT32 val = 0;
03283
03284 if (Target_Byte_Sex == BIG_ENDIAN) {
03285 int k;
03286 for (k = 3*CHAR_BIT; k >= 0; k-=CHAR_BIT) {
03287 val |= vsp_get_bytes(cur_byte,1) << k;
03288 cur_byte++;
03289 }
03290 } else {
03291 int k;
03292 for (k = 0; k < 4*CHAR_BIT; k+=CHAR_BIT) {
03293 val |= vsp_get_bytes(cur_byte,1) << k;
03294 cur_byte++;
03295 }
03296 }
03297
03298 if (j != 0) {
03299 fputs(", ", asm_file);
03300 }
03301
03302 fprintf(asm_file, "0x%08x", (int)val);
03303 }
03304
03305 fputc('\n', asm_file);
03306 }
03307
03308
03309 nlines_this_reloc = (cur_reloc_target - cur_byte) / bytes_per_byte_line;
03310 for (i = 0; i < nlines_this_reloc; i++) {
03311 fputs("\t" AS_BYTE "\t", asm_file);
03312
03313 fprintf(asm_file, "0x%02x",
03314 (int)vsp_get_bytes(cur_byte,1));
03315 cur_byte++;
03316
03317 int j;
03318 for (j = 1; j < bytes_per_byte_line; j++) {
03319 fprintf(asm_file, ", 0x%02x",
03320 (int)vsp_get_bytes(cur_byte,1));
03321 cur_byte++;
03322 }
03323
03324 fputc('\n', asm_file);
03325 }
03326
03327
03328 if (cur_byte != cur_reloc_target) {
03329 fputs("\t" AS_BYTE "\t", asm_file);
03330
03331 fprintf(asm_file, "0x%02x",
03332 (int)vsp_get_bytes(cur_byte,1));
03333 cur_byte++;
03334
03335 for (; cur_byte < cur_reloc_target; cur_byte++) {
03336 fprintf(asm_file, ", 0x%02x",
03337 (int)vsp_get_bytes(cur_byte,1));
03338 }
03339
03340 fputc('\n', asm_file);
03341 }
03342 #endif
03343 return cur_byte - cur_byte_in;
03344 }
03345
03346
03347
03348
03349
03350 static Dwarf_Signed
03351 match_scndx(Elf64_Word scndx,
03352 scn_handle * scn_handles ,
03353 Dwarf_Unsigned section_count ,
03354 scn_handle** scn_bufferp )
03355 {
03356 for (Dwarf_Signed i = 0; i < section_count; i++) {
03357 if (scn_handles[i].sc_scndx == scndx) {
03358 Dwarf_Signed k = 0;
03359 scn_bufferp[k] = scn_handles +i;
03360 ++i;
03361 ++k;
03362 while( i < section_count && scn_handles[i].sc_scndx == scndx ){
03363 scn_bufferp[k] = scn_handles +i;
03364 ++k;
03365 ++i;
03366 }
03367 return k;
03368 }
03369 }
03370 Fail_FmtAssertion("Bogus section index %ld\n", scndx);
03371
03372 }
03373
03374
03375
03376
03377
03378 static Dwarf_Unsigned
03379 compute_buffer_net_size(Dwarf_Signed buffer_cnt,
03380 scn_handle ** buffers)
03381 {
03382 if(buffer_cnt < 1) {
03383 return 0;
03384 }
03385 Dwarf_Unsigned next = 0;
03386 Dwarf_Unsigned totsize = 0;
03387 for( ; next < buffer_cnt; ++next) {
03388 totsize += buffers[next]->sc_bufsize;
03389 }
03390 return totsize;
03391 }
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405 static void
03406 Cg_Dwarf_Output_Asm_Bytes_Elf_Relocs (FILE *asm_file,
03407 const char *section_name,
03408 Elf64_Word section_type,
03409 Elf64_Word section_flags,
03410 Elf64_Word section_entsize,
03411 Elf64_Word section_align,
03412 Dwarf_Signed buffer_cnt,
03413 scn_handle ** buffers,
03414 Elf64_Word reloc_scn_type,
03415 Dwarf_Ptr reloc_buffer,
03416 Dwarf_Unsigned reloc_buffer_size,
03417 BOOL is_64bit)
03418 {
03419
03420 const Dwarf_Unsigned buffer = 0;
03421
03422 CGEMIT_Prn_Scn_In_Asm(asm_file, section_name, section_type,
03423 section_flags, section_entsize,
03424 section_align, NULL);
03425
03426
03427 Dwarf_Unsigned bufsize =
03428 compute_buffer_net_size(buffer_cnt, buffers);
03429
03430 check_reloc_fmt_and_size(reloc_scn_type,
03431 reloc_buffer,
03432 reloc_buffer_size,
03433 bufsize);
03434
03435 Dwarf_Unsigned cur_byte = buffer;
03436
03437
03438 virtual_section_position vsp(buffer_cnt, buffers);
03439
03440 char * current_reloc = (char *) reloc_buffer;
03441
03442
03443
03444
03445 UINT current_reloc_size = (is_64bit ? 8 : 4);
03446
03447 do {
03448 Dwarf_Unsigned current_reloc_target;
03449 if (current_reloc != ((char *) reloc_buffer) + reloc_buffer_size) {
03450 current_reloc_target = (buffer) + reloc_offset(current_reloc,
03451 is_64bit);
03452 }
03453 else {
03454 current_reloc_target = buffer + bufsize;
03455 }
03456 #if defined(Is_True_On)
03457 if ((UINT64) current_reloc_target < (UINT64) cur_byte) {
03458 fprintf(stderr, "ERROR: relocation records not sorted\n");
03459 exit(-1);
03460 }
03461 #endif
03462
03463 cur_byte += vsp.vsp_print_bytes(asm_file,current_reloc_target,cur_byte);
03464
03465 if (cur_byte != (buffer) + bufsize) {
03466 #if defined(Is_True_On)
03467
03468
03469 if ((UINT64) current_reloc_target + current_reloc_size >
03470 (UINT64) buffer + bufsize) {
03471 fprintf(stderr, "ERROR: relocation record overruns end of section data\n");
03472 exit(-1);
03473 }
03474 #endif
03475
03476
03477
03478
03479 Elf64_Word current_reloc_sym_index = reloc_sym_index(current_reloc,
03480 is_64bit);
03481 char *current_reloc_sym_name = Em_Get_Symbol_Name(current_reloc_sym_index);
03482 Dwarf_Unsigned ofst;
03483
03484 #ifdef TARG_MIPS
03485 if (CG_emit_non_gas_syntax)
03486 fprintf(asm_file, "\t%s\t%s", Use_32_Bit_Pointers ? ".word" : ".dword",
03487 current_reloc_sym_name);
03488 else
03489 #endif
03490 fprintf(asm_file, "\t%s\t%s", AS_ADDRESS,
03491 current_reloc_sym_name);
03492
03493 switch (reloc_scn_type) {
03494 case SHT_REL:
03495 if (is_64bit) {
03496 Check_Dwarf_Rel(*((Elf64_AltRel *) current_reloc));
03497 FmtAssert(current_reloc_size == sizeof(UINT64),
03498 ("reloc size error"));
03499 ofst = vsp.vsp_get_bytes(cur_byte,sizeof(UINT64));
03500
03501 #ifdef TARG_IA64
03502 current_reloc += sizeof(Elf64_AltRel);
03503 #else
03504 current_reloc += sizeof(Elf64_Rel);
03505 #endif
03506 }
03507 else {
03508 Check_Dwarf_Rel(*((Elf32_Rel *) current_reloc));
03509 FmtAssert(current_reloc_size == sizeof(UINT32),
03510 ("reloc size error"));
03511 ofst = vsp.vsp_get_bytes(cur_byte,sizeof(UINT32));
03512
03513 current_reloc += sizeof(Elf32_Rel);
03514 }
03515 break;
03516 case SHT_RELA:
03517 if (is_64bit) {
03518 Check_Dwarf_Rela(*((Elf64_AltRela *) current_reloc));
03519
03520
03521 vsp.vsp_get_bytes(cur_byte,sizeof(current_reloc_size));
03522
03523 #ifdef TARG_IA64
03524 ofst = ((Elf64_AltRela *) current_reloc)->r_addend;
03525 current_reloc += sizeof(Elf64_AltRela);
03526 #else
03527 ofst = ((Elf64_Rela *) current_reloc)->r_addend;
03528 current_reloc += sizeof(Elf64_Rela);
03529 #endif
03530 }
03531 else {
03532 Check_Dwarf_Rela(*((Elf32_Rela *) current_reloc));
03533
03534
03535 vsp.vsp_get_bytes(cur_byte,sizeof(current_reloc_size));
03536
03537 ofst = ((Elf32_Rela *) current_reloc)->r_addend;
03538 current_reloc += sizeof(Elf32_Rela);
03539 }
03540 break;
03541 default:
03542 fprintf(stderr,
03543 "ERROR: unrecognized relocation section type: %u\n",
03544 reloc_scn_type);
03545 exit (-1);
03546 }
03547 if (ofst != 0) {
03548 fprintf(asm_file, " + 0x%llx", (unsigned long long)ofst);
03549 }
03550 fputc ('\n', asm_file);
03551 cur_byte += current_reloc_size;
03552 }
03553 } while (cur_byte != ( buffer) + bufsize);
03554 fflush(asm_file);
03555 }
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576 static void
03577 Cg_Dwarf_Output_Asm_Bytes_Sym_Relocs (FILE *asm_file,
03578 const char *section_name,
03579 Elf64_Word section_type,
03580 Elf64_Word section_flags,
03581 Elf64_Word section_entsize,
03582 Elf64_Word section_align,
03583 Dwarf_Signed buffer_cnt,
03584 scn_handle ** buffers,
03585 Dwarf_Relocation_Data reloc_buffer,
03586 Dwarf_Unsigned reloc_count,
03587 BOOL is_64bit)
03588 {
03589
03590
03591
03592 CGEMIT_Prn_Scn_In_Asm(asm_file, section_name, section_type,
03593 section_flags, section_entsize,
03594 section_align, NULL);
03595
03596 const Dwarf_Unsigned buffer = 0;
03597 Dwarf_Unsigned cur_byte = buffer;
03598 Dwarf_Unsigned bufsize = compute_buffer_net_size(buffer_cnt,buffers);
03599
03600 virtual_section_position vsp(buffer_cnt, buffers);
03601
03602 #ifdef KEY
03603 #define buflen 30
03604 char dwarf_begin[buflen], dwarf_end[buflen];
03605 const int alignment = Use_32_Bit_Pointers ? 4 : 8;
03606 #endif
03607
03608 Dwarf_Unsigned k = 0;
03609 while (k <= reloc_count) {
03610
03611
03612
03613
03614
03615 Dwarf_Unsigned current_reloc_target;
03616 if (k != reloc_count) {
03617 current_reloc_target = ( buffer) + reloc_buffer[k].drd_offset;
03618
03619 }
03620 else {
03621 current_reloc_target = ( buffer) + bufsize;
03622 }
03623 #if defined(Is_True_On)
03624 Is_True((UINT64) current_reloc_target >= (UINT64) cur_byte,
03625 ("Relocation records not sorted\n"));
03626 #endif
03627
03628 UINT current_reloc_size = is_64bit?8:4;
03629
03630 if((reloc_count > 0) && reloc_buffer && k < reloc_count) {
03631
03632
03633
03634
03635 current_reloc_size = reloc_buffer[k].drd_length;
03636 }
03637
03638 cur_byte += vsp.vsp_print_bytes(asm_file,current_reloc_target,cur_byte);
03639
03640 if (cur_byte != (buffer) + bufsize) {
03641 #if defined(Is_True_On)
03642
03643
03644 Is_True((UINT64) current_reloc_target + current_reloc_size <=
03645 (UINT64) buffer + bufsize,
03646 ("Relocation record overruns end of section data\n"));
03647 #endif
03648
03649
03650
03651
03652
03653
03654 const char *reloc_name =
03655 #ifdef TARG_MIPS
03656 CG_emit_non_gas_syntax ? (Use_32_Bit_Pointers ? ".word" : ".dword") :
03657 #endif
03658 (reloc_buffer[k].drd_length == 8)?
03659 AS_ADDRESS_UNALIGNED: AS_WORD_UNALIGNED;
03660
03661 #ifdef TARG_X8664
03662
03663
03664 bool gen_pic = ((Gen_PIC_Call_Shared || Gen_PIC_Shared) &&
03665 !strcmp (section_name, EH_FRAME_SECTNAME));
03666 #endif
03667 switch (reloc_buffer[k].drd_type) {
03668 case dwarf_drt_none:
03669 break;
03670 case dwarf_drt_data_reloc:
03671 fprintf(asm_file, "\t%s\t%s", reloc_name,
03672 Cg_Dwarf_Name_From_Handle(reloc_buffer[k].drd_symbol_index));
03673 #ifdef TARG_X8664
03674 if (gen_pic)
03675 fputs ("-.", asm_file);
03676 #endif
03677 break;
03678
03679 case dwarf_drt_segment_rel:
03680
03681 fprintf(asm_file, "\t%s\t%s", reloc_name,
03682 Cg_Dwarf_Name_From_Handle(reloc_buffer[k].drd_symbol_index));
03683 #ifdef TARG_X8664
03684 if (gen_pic)
03685 fprintf(asm_file, "-.");
03686 #endif
03687 break;
03688 #ifdef KEY
03689 case dwarf_drt_cie_label:
03690 #if defined(BUILD_OS_DARWIN)
03691
03692 fprintf(asm_file, "\t%s\t0", reloc_name);
03693 #else
03694 fprintf(asm_file, "\t%s\t%s", reloc_name, ".LCIE");
03695 #endif
03696 ++k;
03697 break;
03698 #ifdef KEY
03699 case dwarf_drt_module:
03700 {
03701 #if ! defined(BUILD_OS_DARWIN)
03702
03703 char *module_name =
03704 (char *)vsp.vsp_buffers[0]->sc_buffer+vsp.vsp_curbufpos+1;
03705 INT length = strlen(module_name);
03706 char *module_name_l = (char *)alloca(length+1);
03707 for (INT pos = 0; pos < length; pos ++)
03708 module_name_l[pos] = tolower(module_name[pos]);
03709 module_name_l[length] = '\0';
03710 fprintf(asm_file, "\t.globl __dm_%s\n__dm_%s:\n",
03711 module_name_l, module_name_l);
03712 #endif
03713 k+=2;
03714
03715
03716 continue;
03717 }
03718 case dwarf_drt_imported_declaration:
03719 {
03720
03721 char *module_name =
03722 (char *)vsp.vsp_buffers[0]->sc_buffer+
03723 vsp.vsp_curbufpos-(reloc_buffer[k].drd_length+1);
03724 reloc_name =
03725 #if defined(BUILD_OS_DARWIN)
03726
03727 (Use_32_Bit_Pointers ? ".word" : ".dword");
03728 #else
03729 #ifdef TARG_MIPS
03730 CG_emit_non_gas_syntax ?
03731 (Use_32_Bit_Pointers ? ".word" : ".dword") :
03732 #endif
03733 AS_ADDRESS;
03734 #endif
03735 fprintf(asm_file, "\t.weak __dm_%s\n\t%s\t__dm_%s\n", module_name,
03736 reloc_name, module_name);
03737 k+=2;
03738
03739
03740 continue;
03741 }
03742 #endif
03743 case dwarf_drt_data_reloc_by_str_id:
03744
03745 if ((Gen_PIC_Call_Shared || Gen_PIC_Shared) &&
03746 !strcmp (&Str_Table[reloc_buffer[k].drd_symbol_index],
03747 "__gxx_personality_v0"))
03748 fprintf (asm_file, "\t%s\tDW.ref.__gxx_personality_v0-.", reloc_name);
03749 else
03750 fprintf(asm_file, "\t%s\t%s", reloc_name,
03751 &Str_Table[reloc_buffer[k].drd_symbol_index]);
03752 break;
03753 case dwarf_drt_first_of_length_pair_create_second:
03754 {
03755 Is_True(k + 1 < reloc_count, ("unpaired first_of_length_pair"));
03756 Is_True((reloc_buffer[k + 1].drd_type ==
03757 dwarf_drt_second_of_length_pair),
03758 ("unpaired first_of_length_pair"));
03759 #ifdef TARG_IA64
03760 static int count=1;
03761 int this_count=count++;
03762 fprintf(asm_file,".LFDE%d:\n",this_count);
03763
03764 fprintf(asm_file, "\t%s\t.LFDE%d - .LEHCIE", reloc_name, this_count);
03765 #else
03766 #if defined(BUILD_OS_DARWIN)
03767
03768
03769 const char *diff = "DIFF.DRT_DATA_RELOC";
03770 fprintf(asm_file, "\t.set %s, %s - .LEHCIE\n"
03771 "%s\t%s\n",
03772 diff, dwarf_begin, reloc_name, diff);
03773 #else
03774
03775 fprintf(asm_file, "\t%s\t%s - .LEHCIE", reloc_name, dwarf_begin);
03776 #endif
03777 #endif
03778 ++k;
03779 }
03780 break;
03781 #endif // KEY
03782 case dwarf_drt_first_of_length_pair:
03783 Is_True(k + 1 < reloc_count, ("unpaired first_of_length_pair"));
03784 Is_True((reloc_buffer[k + 1].drd_type ==
03785 dwarf_drt_second_of_length_pair),
03786 ("unpaired first_of_length_pair"));
03787
03788 #if defined(BUILD_OS_DARWIN)
03789 emit_difference(asm_file, reloc_name,
03790 Cg_Dwarf_Name_From_Handle(reloc_buffer[k + 1].drd_symbol_index),
03791 Cg_Dwarf_Name_From_Handle(reloc_buffer[k].drd_symbol_index));
03792 #else
03793 fprintf(asm_file, "\t%s\t%s - %s", reloc_name,
03794 Cg_Dwarf_Name_From_Handle(reloc_buffer[k + 1].drd_symbol_index),
03795 Cg_Dwarf_Name_From_Handle(reloc_buffer[k].drd_symbol_index));
03796 #endif
03797 ++k;
03798 break;
03799 case dwarf_drt_second_of_length_pair:
03800 Fail_FmtAssertion("unpaired first/second_of_length_pair");
03801 break;
03802 #ifdef KEY
03803
03804 case dwarf_drt_cie_begin:
03805 {
03806 Is_True (!strcmp (section_name, EH_FRAME_SECTNAME),
03807 ("This is valid only for EH_FRAME section"));
03808
03809 static int cie_count = 0;
03810 cie_count++;
03811
03812
03813 FmtAssert (cie_count == 1, ("Multiple CIEs not supported"));
03814
03815 BZERO (dwarf_begin, buflen);
03816 BZERO (dwarf_end, buflen);
03817
03818 strcpy (dwarf_begin, ".LEHCIE_begin");
03819 strcpy (dwarf_end, ".LEHCIE_end");
03820
03821 #if defined(BUILD_OS_DARWIN)
03822 emit_difference(asm_file, reloc_name, dwarf_end, dwarf_begin);
03823 #else
03824 fprintf (asm_file, "\t%s\t%s - %s\n", reloc_name,
03825 dwarf_end, dwarf_begin);
03826 #endif
03827
03828 fprintf (asm_file, "%s:", dwarf_begin);
03829 }
03830 break;
03831
03832 case dwarf_drt_fde_begin:
03833 {
03834 Is_True (!strcmp (section_name, EH_FRAME_SECTNAME),
03835 ("This is valid only for EH_FRAME section"));
03836
03837
03838 #if defined(BUILD_OS_DARWIN)
03839 fprintf (asm_file, "\t%s %d\n", AS_ALIGN, logtwo(alignment));
03840 #else
03841 fprintf (asm_file, "\t%s %d\n", AS_ALIGN, alignment);
03842 #endif
03843 fprintf (asm_file, "%s:\n", dwarf_end);
03844
03845
03846 static int count = 1;
03847 int this_count = count++;
03848 BZERO (dwarf_begin, buflen);
03849 BZERO (dwarf_end, buflen);
03850
03851
03852 sprintf (dwarf_begin, ".LFDE%d_begin", this_count);
03853 sprintf (dwarf_end, ".LFDE%d_end", this_count);
03854
03855 #if defined(BUILD_OS_DARWIN)
03856 emit_difference(asm_file, reloc_name, dwarf_end, dwarf_begin);
03857 #else
03858 fprintf (asm_file, "\t%s\t%s - %s\n", reloc_name, dwarf_end, dwarf_begin);
03859 #endif
03860
03861 fprintf (asm_file, "%s:", dwarf_begin);
03862 }
03863 break;
03864 #endif // KEY
03865 default:
03866 break;
03867 }
03868
03869 Dwarf_Unsigned ofst;
03870 if (current_reloc_size == 8) {
03871
03872 ofst = vsp.vsp_get_bytes(cur_byte,8);
03873 }
03874 else if(current_reloc_size == 4){
03875
03876
03877
03878 ofst = vsp.vsp_get_bytes(cur_byte,4);
03879 } else {
03880 Fail_FmtAssertion("current_reloc_size %ld, 4 or 8 required!\n",
03881 (long)current_reloc_size);
03882 }
03883 #ifdef TARG_X8664
03884
03885
03886 if (ofst == 0 && cur_byte == 4 && strcmp(section_name, EH_FRAME_SECTNAME) == 0)
03887 fprintf(asm_file, "\t%s 0x%llx", reloc_name, (unsigned long long)ofst);
03888 #endif
03889 if (ofst != 0) {
03890 #ifdef KEY
03891 if (reloc_buffer[k].drd_type == dwarf_drt_none)
03892 fprintf(asm_file, "\t%s 0x%llx", reloc_name, (unsigned long long)ofst);
03893 else
03894 #endif // KEY
03895 fprintf(asm_file, " + 0x%llx", (unsigned long long)ofst);
03896 }
03897 fputc ('\n', asm_file);
03898 cur_byte += current_reloc_size;
03899 }
03900 ++k;
03901 }
03902
03903 #ifdef KEY
03904 if (!strcmp (section_name, EH_FRAME_SECTNAME)){
03905
03906 #if defined(BUILD_OS_DARWIN)
03907 fprintf (asm_file, "\t%s %d\n", AS_ALIGN, logtwo(alignment));
03908 #else
03909 fprintf (asm_file, "\t%s %d\n", AS_ALIGN, alignment);
03910 #endif
03911 if (strcmp (dwarf_end, ""))
03912 fprintf (asm_file, "%s:\n", dwarf_end);
03913 }
03914 #endif
03915
03916 fflush(asm_file);
03917 }
03918
03919
03920 #if !defined(LIBDWARF_SORTS_RELOCS)
03921 static int compare_rel64(const void *const a, const void *const b)
03922 {
03923 #ifdef TARG_IA64
03924 if (REL_offset(*((Elf64_AltRel *) a)) < REL_offset(*((Elf64_AltRel *) b))) {
03925 #else
03926 if (REL_offset(*((Elf64_Rel *) a)) < REL_offset(*((Elf64_Rel *) b))) {
03927 #endif
03928 return -1;
03929 }
03930 #ifdef TARG_IA64
03931 else if (REL_offset(*((Elf64_AltRel *) a)) > REL_offset(*((Elf64_AltRel *) b))) {
03932 #else
03933 else if (REL_offset(*((Elf64_Rel *) a)) > REL_offset(*((Elf64_Rel *) b))) {
03934 #endif
03935 return 1;
03936 }
03937 else {
03938 return 0;
03939 }
03940 }
03941
03942 static int compare_rela64(const void *const a, const void *const b)
03943 {
03944 #ifdef TARG_IA64
03945 if (REL_offset(*((Elf64_AltRela *) a)) < REL_offset(*((Elf64_AltRela *) b))) {
03946 #else
03947 if (REL_offset(*((Elf64_Rela *) a)) < REL_offset(*((Elf64_Rela *) b))) {
03948 #endif
03949 return -1;
03950 }
03951 #ifdef TARG_IA64
03952 else if (REL_offset(*((Elf64_AltRela *) a)) > REL_offset(*((Elf64_AltRela *) b))) {
03953 #else
03954 else if (REL_offset(*((Elf64_Rela *) a)) > REL_offset(*((Elf64_Rela *) b))) {
03955 #endif
03956 return 1;
03957 }
03958 else {
03959 return 0;
03960 }
03961 }
03962
03963 static int compare_rel32(const void *const a, const void *const b)
03964 {
03965 if (REL32_offset(*((Elf32_Rel *) a)) < REL32_offset(*((Elf32_Rel *) b))) {
03966 return -1;
03967 }
03968 else if (REL32_offset(*((Elf32_Rel *) a)) > REL32_offset(*((Elf32_Rel *) b))) {
03969 return 1;
03970 }
03971 else {
03972 return 0;
03973 }
03974 }
03975
03976 static int compare_rela32(const void *const a, const void *const b)
03977 {
03978 if (REL32_offset(*((Elf32_Rela *) a)) < REL32_offset(*((Elf32_Rela *) b))) {
03979 return -1;
03980 }
03981 else if (REL32_offset(*((Elf32_Rela *) a)) > REL32_offset(*((Elf32_Rela *) b))) {
03982 return 1;
03983 }
03984 else {
03985 return 0;
03986 }
03987 }
03988 #endif
03989
03990 void
03991 Cg_Dwarf_Write_Assembly_From_Elf (FILE *asm_file,
03992 INT section_count,
03993 BOOL is_64bit)
03994 {
03995 Dwarf_Signed i;
03996 Dwarf_Ptr buffer;
03997 Dwarf_Signed scndx;
03998 Dwarf_Unsigned bufsize;
03999 pSCNINFO cursection;
04000 scn_handle *scn_handles =
04001 (scn_handle *) malloc(section_count * sizeof(scn_handle));
04002 FmtAssert(scn_handles != 0,
04003 ("malloc space for scn_handles failed"));
04004 scn_handle *s = scn_handles;
04005
04006 scn_handle ** scn_buffers =
04007 (scn_handle **) malloc(section_count * sizeof(scn_handle *));
04008 FmtAssert(scn_buffers != 0,
04009 ("malloc space for scn_buffers failed"));
04010
04011 dwarf_reset_section_bytes(dw_dbg);
04012
04013 for (i = 0; i < section_count; i++) {
04014 s = scn_handles + i;
04015 buffer = dwarf_get_section_bytes (dw_dbg, i, &scndx, &bufsize, &dw_error);
04016 cursection = Em_Dwarf_Find_Dwarf_Scn (scndx);
04017 if (cursection != NULL) {
04018 s->sc_buffer = buffer;
04019 s->sc_bufsize = bufsize;
04020 s->sc_scndx = scndx;
04021 s->sc_cursection = cursection;
04022 s->sc_output = FALSE;
04023 }
04024 else {
04025 fprintf (stderr, "ERROR No such section index: %d\n", (int)scndx);
04026 exit(-1);
04027 }
04028 }
04029
04030
04031
04032 for (i = 0; i < section_count; i++) {
04033 pSCNINFO relsection = scn_handles[i].sc_cursection;
04034 Elf64_Word relsection_type = Em_Get_Section_Type(relsection);
04035
04036 if (relsection_type == SHT_REL || relsection_type == SHT_RELA) {
04037
04038 #if defined(LIBDWARF_SORTS_RELOCS)
04039 char *reloc_sorted = (char *) scn_handles[i].sc_buffer;
04040 #else
04041 char *reloc_sorted = (char *) malloc(scn_handles[i].sc_bufsize);
04042 reloc_sorted = (char *) memcpy((void *) reloc_sorted,
04043 (void *) scn_handles[i].sc_buffer,
04044 (size_t) scn_handles[i].sc_bufsize);
04045 size_t n_relocs;
04046 if (relsection_type == SHT_REL) {
04047 if (is_64bit) {
04048 #ifdef TARG_IA64
04049 n_relocs = scn_handles[i].sc_bufsize / sizeof(Elf64_AltRel);
04050 qsort(reloc_sorted, n_relocs, sizeof(Elf64_AltRel), compare_rel64);
04051 #else
04052 n_relocs = scn_handles[i].sc_bufsize / sizeof(Elf64_Rel);
04053 qsort(reloc_sorted, n_relocs, sizeof(Elf64_Rel), compare_rel64);
04054 #endif
04055 }
04056 else {
04057 n_relocs = scn_handles[i].sc_bufsize / sizeof(Elf32_Rel);
04058 qsort(reloc_sorted, n_relocs, sizeof(Elf32_Rel), compare_rel32);
04059 }
04060 }
04061 else {
04062 if (is_64bit) {
04063 #ifdef TARG_IA64
04064 n_relocs = scn_handles[i].sc_bufsize / sizeof(Elf64_AltRela);
04065 qsort(reloc_sorted, n_relocs, sizeof(Elf64_AltRela), compare_rela64);
04066 #else
04067 n_relocs = scn_handles[i].sc_bufsize / sizeof(Elf64_Rela);
04068 qsort(reloc_sorted, n_relocs, sizeof(Elf64_Rela), compare_rela64);
04069 #endif
04070 }
04071 else {
04072 qsort(reloc_sorted, n_relocs, sizeof(Elf32_Rela), compare_rela32);
04073 }
04074 }
04075 #endif
04076
04077
04078
04079
04080 Elf64_Word relsection_info = Em_Get_Section_Info(relsection);
04081
04082 Dwarf_Signed scn_count = match_scndx(relsection_info,
04083 scn_handles,
04084 section_count,
04085 scn_buffers);
04086 cursection = scn_buffers[0]->sc_cursection;
04087
04088 char *section_name = Em_Get_Section_Name(cursection);
04089 Elf64_Word section_type = Em_Get_Section_Type(cursection);
04090 Elf64_Word section_flags = Em_Get_Section_Flags(cursection);
04091 Elf64_Word section_entsize = Em_Get_Section_Entsize(cursection);
04092 Elf64_Word section_align = Em_Get_Section_Align(cursection);
04093 Cg_Dwarf_Output_Asm_Bytes_Elf_Relocs (asm_file, section_name,
04094 section_type, section_flags,
04095 section_entsize, section_align,
04096 scn_count,
04097 scn_buffers,
04098 relsection_type,
04099 reloc_sorted,
04100 scn_handles[i].sc_bufsize,
04101 is_64bit);
04102 #if !defined(LIBDWARF_SORTS_RELOCS)
04103 free(reloc_sorted);
04104 #endif
04105 }
04106 }
04107 free(scn_handles);
04108 scn_handles = NULL;
04109 free(scn_buffers);
04110 scn_buffers = 0;
04111 }
04112
04113 void
04114 Cg_Dwarf_Write_Assembly_From_Symbolic_Relocs (FILE *asm_file,
04115 INT section_count,
04116 BOOL is_64bit)
04117 {
04118 Dwarf_Signed i;
04119 Dwarf_Ptr buffer;
04120 Dwarf_Signed scndx;
04121 Dwarf_Unsigned bufsize;
04122 pSCNINFO cursection;
04123 scn_handle *scn_handles;
04124 scn_handle *s;
04125
04126 scn_handles = (scn_handle *) malloc(section_count * sizeof(scn_handle));
04127 FmtAssert(scn_handles != 0,
04128 ("malloc space for scn_handles failed"));
04129 scn_handle ** scn_buffers =
04130 (scn_handle **) malloc(section_count * sizeof(scn_handle *));
04131 FmtAssert(scn_buffers != 0,
04132 ("malloc space for scn_buffers failed"));
04133
04134
04135 dwarf_reset_section_bytes(dw_dbg);
04136
04137 for (i = 0; i < section_count; i++) {
04138 s = scn_handles + i;
04139
04140 buffer = dwarf_get_section_bytes (dw_dbg, i, &scndx, &bufsize, &dw_error);
04141 cursection = Em_Dwarf_Find_Dwarf_Scn (scndx);
04142 if (cursection != NULL) {
04143 s->sc_buffer = buffer;
04144 s->sc_bufsize = bufsize;
04145 s->sc_scndx = scndx;
04146 s->sc_cursection = cursection;
04147 s->sc_output = FALSE;
04148 } else {
04149 fprintf (stderr, "ERROR No such section index: %d\n", (int)scndx);
04150 exit(-1);
04151 }
04152 }
04153
04154
04155
04156 Dwarf_Unsigned relocation_section_count;
04157 int reloc_buffer_version;
04158 int result = dwarf_get_relocation_info_count(dw_dbg,
04159 &relocation_section_count,
04160 &reloc_buffer_version,
04161 &dw_error);
04162 FmtAssert(result == DW_DLV_OK,
04163 ("Failure to get relocation info count"));
04164 Is_True(reloc_buffer_version == 2,
04165 ("Symbolic relocation format mismatch"));
04166
04167 for (i = 0; i < relocation_section_count; i++) {
04168 Dwarf_Relocation_Data reloc_buf;
04169 Dwarf_Unsigned entry_count;
04170 Dwarf_Signed link_scn;
04171
04172 result = dwarf_get_relocation_info(dw_dbg, &scndx, &link_scn,
04173 &entry_count, &reloc_buf,
04174 &dw_error);
04175 FmtAssert(result == DW_DLV_OK,
04176 ("Failure to get relocation info"));
04177
04178
04179
04180 Dwarf_Signed scn_count = match_scndx(link_scn,
04181 scn_handles,
04182 section_count,
04183 scn_buffers);
04184
04185
04186 cursection = scn_buffers[0]->sc_cursection;
04187
04188 char *section_name = Em_Get_Section_Name(cursection);
04189
04190
04191 if(TRUE == Is_Dwarf_Section_To_Emit(section_name)) {
04192 Elf64_Word section_type = Em_Get_Section_Type(cursection);
04193 Elf64_Word section_flags = Em_Get_Section_Flags(cursection);
04194 Elf64_Word section_entsize = Em_Get_Section_Entsize(cursection);
04195 Elf64_Word section_align = Em_Get_Section_Align(cursection);
04196 Cg_Dwarf_Output_Asm_Bytes_Sym_Relocs (asm_file, section_name,
04197 section_type, section_flags,
04198 section_entsize, section_align,
04199 scn_count,
04200 scn_buffers,
04201 reloc_buf,
04202 entry_count, is_64bit);
04203 }
04204 #ifdef TARG_X8664
04205
04206
04207
04208
04209
04210
04211 else if (strcmp(section_name, DEBUG_LINE_SECTNAME) == 0)
04212 #if defined(BUILD_OS_DARWIN)
04213 gen_debug_line_section_header(asm_file, section_name);
04214 #else
04215 fputs("\n\t.section " DEBUG_LINE_SECTNAME ", \"\"\n", asm_file);
04216 #endif
04217 #endif
04218 for(int i = 0; i < scn_count; ++i) {
04219 scn_buffers[i]->sc_output = TRUE;
04220 }
04221 }
04222
04223 for (i = 0; i < section_count; i++) {
04224 if (!scn_handles[i].sc_output) {
04225 cursection = scn_handles[i].sc_cursection;
04226 char *section_name = Em_Get_Section_Name(cursection);
04227 scn_handle *one_han = scn_handles +i;
04228
04229
04230 if(TRUE == Is_Dwarf_Section_To_Emit(section_name)) {
04231 Elf64_Word section_type = Em_Get_Section_Type(cursection);
04232 Elf64_Word section_flags = Em_Get_Section_Flags(cursection);
04233 Elf64_Word section_entsize = Em_Get_Section_Entsize(cursection);
04234 Elf64_Word section_align = Em_Get_Section_Align(cursection);
04235 Cg_Dwarf_Output_Asm_Bytes_Sym_Relocs (asm_file, section_name,
04236 section_type, section_flags,
04237 section_entsize, section_align,
04238 1,
04239 &one_han,
04240 NULL,
04241 0,
04242 is_64bit);
04243 }
04244 #ifdef TARG_X8664
04245
04246
04247
04248
04249
04250
04251 else if (strcmp(section_name, DEBUG_LINE_SECTNAME) == 0)
04252 #if defined(BUILD_OS_DARWIN)
04253 gen_debug_line_section_header(asm_file, section_name);
04254 #else
04255 fputs("\n\t.section " DEBUG_LINE_SECTNAME ", \"\"\n", asm_file);
04256 #endif
04257 #endif
04258 }
04259 }
04260
04261 free(scn_handles);
04262 scn_handles = NULL;
04263 free(scn_buffers);
04264 scn_buffers = 0;
04265 }