From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jim Blandy To: gdb-patches@sources.redhat.com Subject: RFC: partial symbol table address range generalization Date: Tue, 23 Oct 2001 16:33:00 -0000 Message-id: <20011023233450.09F855E9D8@zwingli.cygnus.com> X-SW-Source: 2001-10/msg00304.html This is the first patch in a series. If you are interested in GDB's symbol table, I'd appreciate your comments and review. The Problem: At the moment, GDB's partial symbol table structures assume that each compilation unit's text occupies a single contiguous range of addresses. If a given address falls between a `struct partial_symtab' structure's `texthigh' and `textlow' addresses, then GDB assumes that reading that partial symbol table's debugging info will provide complete information about that address. However, this assumption isn't true. A given .o file's code can actually appear in any number of distinct regions, separated by code from other .o files. This can happen when we compile and link a C++ program, like the below (from GCC's test suite): // Special g++ Options: -fexceptions -g // excess errors test - XFAIL a29k-*-* sparc64-*-elf arm-*-pe class zeroset { public: ~zeroset () { } }; int main () { zeroset a; try { ; } catch( zeroset ) { } } G++ puts the code for `main' in the .o file's .text section, and the code for the `zeroset' destructor in a section named .gnu.linkonce.t._ZN7zerosetD1Ev. The linker script gathers all the .o files' .text sections together, followed by all the .gnu.linkonce.t.* sections. As a result, library functions' code appears between that for `main' and the `zeroset' destructor in the final executable. As a result, GDB builds a `struct partial_symtab' for the above source file whose `textlow' and `texthigh' range encloses not only the code for `main' and the destructor, but all the library functions' code as well. There is some logic in GDB's lookup functions to cope with overlapping partial symtabs, and they've been working pretty well on our behalf. However, they're fragile, and do break in everyday use. For example, in the executable produced from the source file above, if you try to set a breakpoint on a library routine compiled without debug information, GDB will set the breakpoint in `main' instead. (On some platforms, `_exit' is such a function.) It is possible to change the linker script to link all a .o file's sections together, but the linker scripts that are currently in widespread use do not, and the same situation can arise in other circumstances (reordered executables, for example). The Solution: I'd like to change GDB's `struct partial_symtab' structure to cover an arbitrary set of addresses, not just a single contiguous span of addresses. I've written code for a `struct addrset' datatype (essentially a linked list of ranges) and provided some functions to make it easy and robust to work with. I'd like to gradually wean the partial symbol table code away from the textlow/texthigh representation, and have it use an addrset to represent a partial symbol table's coverage. This isn't a complete solution: - Code that works with the full symbol table still uses each `struct symtab's global block's `startaddr' and `endaddr' members to find the `struct symtab' that covers a given address; this suffers from the same problem as the current partial symtabs. - Changing the STABS partial symbol table scanner to recognize non-contiguous .o files seems like it should be possible, but I wasn't able to do it in a way that I was sure wouldn't break any targets. So for now, I'm going to leave the STABS reader alone; the data structures will be capable of describing non-contiguous .o files on STABS platforms, but the reader will never recognize them. However, Dwarf 2 does provide the information in a reliable way, and this change will be useful in that case. Below is the first patch in the series. It's meant to have no effect on GDB's behavior. 2001-10-23 Jim Blandy Isolate STABS readers' use of the `textlow' and `texthigh' fields of `struct partial_symtab' to only a few locations. This change is not supposed to affect the way the values are computed, only where they live. * dbxread.c (struct symloc): Add `textlow' and `texthigh' fields to the reader-specific structure. * mdebugread.c (struct symloc): Same. * dbxread.c (TEXTLOW, TEXTHIGH): New accessor macros. * mdebugread.c (TEXTLOW, TEXTHIGH): Same. * dbxread.c (dbx_symfile_read): After we've built all our partial symbol tables, set each partial symtab's `textlow' and `texthigh' fields from our reader-specific structure. * mdebugread.c (mdebug_build_psymtabs): Same. * dbxread.c (start_psymtab): Initialize the reader-specific structure's `textlow' and `texthigh' from the new psymtab's. * mdebugread.c (parse_partial_symbols, new_psymtab): Same. * dbxread.c (read_dbx_symtab, end_psymtab, read_ofile_symtab): Use the reader-specific `textlow' and `texthigh', not the generic psymtab fields. * mdebugread.c (parse_lines, parse_partial_symbols, psymtab_to_symtab_1): Same. * partial-stab.h: Same. Index: gdb/dbxread.c =================================================================== RCS file: /cvs/src/src/gdb/dbxread.c,v retrieving revision 1.24 diff -c -r1.24 dbxread.c *** gdb/dbxread.c 2001/09/20 03:03:39 1.24 --- gdb/dbxread.c 2001/10/23 23:14:38 *************** *** 76,81 **** --- 76,87 ---- struct symloc { + /* STABS doesn't reliably give us nice start and end addresses for + each function. Instead, we are told the addresses of various + boundary points, and we have to gather those together to build + ranges. These are our running best guess as to the range of + text addresses for this psymtab. */ + CORE_ADDR textlow, texthigh; /* Offset within the file symbol table of first local symbol for this file. */ *************** *** 105,110 **** --- 111,118 ---- #define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff) #define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen) #define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private)) + #define TEXTLOW(p) (SYMLOC(p)->textlow) + #define TEXTHIGH(p) (SYMLOC(p)->texthigh) #define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size) #define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset) #define STRING_OFFSET(p) (SYMLOC(p)->string_offset) *************** *** 599,604 **** --- 607,625 ---- read_dbx_dynamic_symtab (objfile); + /* Take the text ranges the STABS partial symbol scanner computed + for each of the psymtabs and convert it into the canonical form + for psymtabs. */ + { + struct partial_symtab *p; + + ALL_OBJFILE_PSYMTABS (objfile, p) + { + p->textlow = TEXTLOW (p); + p->texthigh = TEXTHIGH (p); + } + } + /* Install any minimal symbols that have been collected as the current minimal symbols for this objfile. */ *************** *** 1341,1347 **** end_psymtab (pst, psymtab_include_list, includes_used, symnum * symbol_size, ! text_end > pst->texthigh ? text_end : pst->texthigh, dependency_list, dependencies_used, textlow_not_set); } --- 1362,1368 ---- end_psymtab (pst, psymtab_include_list, includes_used, symnum * symbol_size, ! text_end > TEXTHIGH (pst) ? text_end : TEXTHIGH (pst), dependency_list, dependencies_used, textlow_not_set); } *************** *** 1367,1372 **** --- 1388,1395 ---- result->read_symtab_private = (char *) obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc)); + TEXTLOW (result) = result->textlow; + TEXTHIGH (result) = result->texthigh; LDSYMOFF (result) = ldsymoff; result->read_symtab = dbx_psymtab_to_symtab; SYMBOL_SIZE (result) = symbol_size; *************** *** 1402,1408 **** if (capping_symbol_offset != -1) LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst); ! pst->texthigh = capping_text; #ifdef SOFUN_ADDRESS_MAYBE_MISSING /* Under Solaris, the N_SO symbols always have a value of 0, --- 1425,1431 ---- if (capping_symbol_offset != -1) LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst); ! TEXTHIGH (pst) = capping_text; #ifdef SOFUN_ADDRESS_MAYBE_MISSING /* Under Solaris, the N_SO symbols always have a value of 0, *************** *** 1420,1426 **** a reliable texthigh by taking the address plus size of the last function in the file. */ ! if (pst->texthigh == 0 && last_function_name) { char *p; int n; --- 1443,1449 ---- a reliable texthigh by taking the address plus size of the last function in the file. */ ! if (TEXTHIGH (pst) == 0 && last_function_name) { char *p; int n; *************** *** 1446,1459 **** } if (minsym) ! pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym); last_function_name = NULL; } /* this test will be true if the last .o file is only data */ if (textlow_not_set) ! pst->textlow = pst->texthigh; else { struct partial_symtab *p1; --- 1469,1482 ---- } if (minsym) ! TEXTHIGH (pst) = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym); last_function_name = NULL; } /* this test will be true if the last .o file is only data */ if (textlow_not_set) ! TEXTLOW (pst) = TEXTHIGH (pst); else { struct partial_symtab *p1; *************** *** 1466,1477 **** ALL_OBJFILE_PSYMTABS (objfile, p1) { ! if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst) { ! p1->texthigh = pst->textlow; /* if this file has only data, then make textlow match texthigh */ ! if (p1->textlow == 0) ! p1->textlow = p1->texthigh; } } } --- 1489,1500 ---- ALL_OBJFILE_PSYMTABS (objfile, p1) { ! if (TEXTHIGH (p1) == 0 && TEXTLOW (p1) != 0 && p1 != pst) { ! TEXTHIGH (p1) = TEXTLOW (pst); /* if this file has only data, then make textlow match texthigh */ ! if (TEXTLOW (p1) == 0) ! TEXTLOW (p1) = TEXTHIGH (p1); } } } *************** *** 1508,1515 **** sizeof (struct symloc)); LDSYMOFF (subpst) = LDSYMLEN (subpst) = ! subpst->textlow = ! subpst->texthigh = 0; /* We could save slight bits of space by only making one of these, shared by the entire set of include files. FIXME-someday. */ --- 1531,1538 ---- sizeof (struct symloc)); LDSYMOFF (subpst) = LDSYMLEN (subpst) = ! TEXTLOW (subpst) = ! TEXTHIGH (subpst) = 0; /* We could save slight bits of space by only making one of these, shared by the entire set of include files. FIXME-someday. */ *************** *** 1677,1684 **** objfile = pst->objfile; sym_offset = LDSYMOFF (pst); sym_size = LDSYMLEN (pst); ! text_offset = pst->textlow; ! text_size = pst->texthigh - pst->textlow; /* This cannot be simply objfile->section_offsets because of elfstab_offset_sections() which initializes the psymtab section offsets information in a special way, and that is different from --- 1700,1707 ---- objfile = pst->objfile; sym_offset = LDSYMOFF (pst); sym_size = LDSYMLEN (pst); ! text_offset = TEXTLOW (pst); ! text_size = TEXTHIGH (pst) - TEXTLOW (pst); /* This cannot be simply objfile->section_offsets because of elfstab_offset_sections() which initializes the psymtab section offsets information in a special way, and that is different from *************** *** 1823,1835 **** /* In a Solaris elf file, this variable, which comes from the value of the N_SO symbol, will still be 0. Luckily, text_offset, ! which comes from pst->textlow is correct. */ if (last_source_start_addr == 0) last_source_start_addr = text_offset; /* In reordered executables last_source_start_addr may not be the lower bound for this symtab, instead use text_offset which comes ! from pst->textlow which is correct. */ if (last_source_start_addr > text_offset) last_source_start_addr = text_offset; --- 1846,1858 ---- /* In a Solaris elf file, this variable, which comes from the value of the N_SO symbol, will still be 0. Luckily, text_offset, ! which comes from TEXTLOW (pst) is correct. */ if (last_source_start_addr == 0) last_source_start_addr = text_offset; /* In reordered executables last_source_start_addr may not be the lower bound for this symtab, instead use text_offset which comes ! from TEXTLOW (pst) which is correct. */ if (last_source_start_addr > text_offset) last_source_start_addr = text_offset; Index: gdb/mdebugread.c =================================================================== RCS file: /cvs/src/src/gdb/mdebugread.c,v retrieving revision 1.16 diff -c -r1.16 mdebugread.c *** gdb/mdebugread.c 2001/10/12 23:51:28 1.16 --- gdb/mdebugread.c 2001/10/23 23:14:41 *************** *** 105,110 **** --- 105,115 ---- struct symloc { + /* Our running best guess as to the range of text addresses for + this psymtab. After we've read everything in, we use this to + build pst->text_addrs. */ + CORE_ADDR textlow, texthigh; + /* Index of the FDR that this psymtab represents. */ int fdr_idx; /* The BFD that the psymtab was created from. */ *************** *** 120,125 **** --- 125,132 ---- }; #define PST_PRIVATE(p) ((struct symloc *)(p)->read_symtab_private) + #define TEXTLOW(p) (PST_PRIVATE(p)->textlow) + #define TEXTHIGH(p) (PST_PRIVATE(p)->texthigh) #define FDR_IDX(p) (PST_PRIVATE(p)->fdr_idx) #define CUR_BFD(p) (PST_PRIVATE(p)->cur_bfd) #define DEBUG_SWAP(p) (PST_PRIVATE(p)->debug_swap) *************** *** 516,521 **** --- 523,541 ---- parse_partial_symbols (objfile); + /* Take the text ranges the partial symbol scanner computed for each + of the psymtabs and convert it into the canonical form for + psymtabs. */ + { + struct partial_symtab *p; + + ALL_OBJFILE_PSYMTABS (objfile, p) + { + p->textlow = TEXTLOW (p); + p->texthigh = TEXTHIGH (p); + } + } + #if 0 /* Check to make sure file was compiled with -g. If not, warn the user of this limitation. */ *************** *** 2174,2180 **** halt = base + fh->cbLine; base += pr->cbLineOffset; ! adr = pst->textlow + pr->adr - lowest_pdr_addr; l = adr >> 2; /* in words */ for (lineno = pr->lnLow; base < halt;) --- 2194,2200 ---- halt = base + fh->cbLine; base += pr->cbLineOffset; ! adr = TEXTLOW (pst) + pr->adr - lowest_pdr_addr; l = adr >> 2; /* in words */ for (lineno = pr->lnLow; base < halt;) *************** *** 2509,2514 **** --- 2529,2536 ---- memset ((PTR) pst->read_symtab_private, 0, sizeof (struct symloc)); save_pst = pst; + TEXTLOW (pst) = pst->textlow; + TEXTHIGH (pst) = pst->texthigh; FDR_IDX (pst) = f_idx; CUR_BFD (pst) = cur_bfd; DEBUG_SWAP (pst) = debug_swap; *************** *** 2544,2550 **** psymtab_language = prev_language; PST_PRIVATE (pst)->pst_language = psymtab_language; ! pst->texthigh = pst->textlow; /* For stabs-in-ecoff files, the second symbol must be @stab. This symbol is emitted by mips-tfile to signal that the --- 2566,2572 ---- psymtab_language = prev_language; PST_PRIVATE (pst)->pst_language = psymtab_language; ! TEXTHIGH (pst) = TEXTLOW (pst); /* For stabs-in-ecoff files, the second symbol must be @stab. This symbol is emitted by mips-tfile to signal that the *************** *** 2611,2620 **** /* Kludge for Irix 5.2 zero fh->adr. */ if (!relocatable ! && (pst->textlow == 0 || procaddr < pst->textlow)) ! pst->textlow = procaddr; ! if (high > pst->texthigh) ! pst->texthigh = high; } } else if (sh.st == stStatic) --- 2633,2642 ---- /* Kludge for Irix 5.2 zero fh->adr. */ if (!relocatable ! && (TEXTLOW (pst) == 0 || procaddr < TEXTLOW (pst))) ! TEXTLOW (pst) = procaddr; ! if (high > TEXTHIGH (pst)) ! TEXTHIGH (pst) = high; } } else if (sh.st == stStatic) *************** *** 2703,2709 **** (pst = save_pst) #define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps,textlow_not_set) (void)0 #define HANDLE_RBRAC(val) \ ! if ((val) > save_pst->texthigh) save_pst->texthigh = (val); #include "partial-stab.h" if (stabstring --- 2725,2731 ---- (pst = save_pst) #define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps,textlow_not_set) (void)0 #define HANDLE_RBRAC(val) \ ! if ((val) > TEXTHIGH (save_pst)) TEXTHIGH (save_pst) = (val); #include "partial-stab.h" if (stabstring *************** *** 2836,2847 **** /* Kludge for Irix 5.2 zero fh->adr. */ if (!relocatable ! && (pst->textlow == 0 || procaddr < pst->textlow)) ! pst->textlow = procaddr; high = procaddr + sh.value; ! if (high > pst->texthigh) ! pst->texthigh = high; continue; case stStatic: /* Variable */ --- 2858,2869 ---- /* Kludge for Irix 5.2 zero fh->adr. */ if (!relocatable ! && (TEXTLOW (pst) == 0 || procaddr < TEXTLOW (pst))) ! TEXTLOW (pst) = procaddr; high = procaddr + sh.value; ! if (high > TEXTHIGH (pst)) ! TEXTHIGH (pst) = high; continue; case stStatic: /* Variable */ *************** *** 3015,3030 **** empty and put on the free list. */ fdr_to_pst[f_idx].pst = end_psymtab (save_pst, psymtab_include_list, includes_used, ! -1, save_pst->texthigh, dependency_list, dependencies_used, textlow_not_set); includes_used = 0; dependencies_used = 0; ! if (objfile->ei.entry_point >= save_pst->textlow && ! objfile->ei.entry_point < save_pst->texthigh) { ! objfile->ei.entry_file_lowpc = save_pst->textlow; ! objfile->ei.entry_file_highpc = save_pst->texthigh; } /* The objfile has its functions reordered if this partial symbol --- 3037,3052 ---- empty and put on the free list. */ fdr_to_pst[f_idx].pst = end_psymtab (save_pst, psymtab_include_list, includes_used, ! -1, TEXTHIGH (save_pst), dependency_list, dependencies_used, textlow_not_set); includes_used = 0; dependencies_used = 0; ! if (objfile->ei.entry_point >= TEXTLOW (save_pst) && ! objfile->ei.entry_point < TEXTHIGH (save_pst)) { ! objfile->ei.entry_file_lowpc = TEXTLOW (save_pst); ! objfile->ei.entry_file_highpc = TEXTHIGH (save_pst); } /* The objfile has its functions reordered if this partial symbol *************** *** 3040,3054 **** other cases. */ save_pst = fdr_to_pst[f_idx].pst; if (save_pst != NULL ! && save_pst->textlow != 0 && !(objfile->flags & OBJF_REORDERED)) { ALL_OBJFILE_PSYMTABS (objfile, pst) { if (save_pst != pst ! && save_pst->textlow >= pst->textlow ! && save_pst->textlow < pst->texthigh ! && save_pst->texthigh > pst->texthigh) { objfile->flags |= OBJF_REORDERED; break; --- 3062,3076 ---- other cases. */ save_pst = fdr_to_pst[f_idx].pst; if (save_pst != NULL ! && TEXTLOW (save_pst) != 0 && !(objfile->flags & OBJF_REORDERED)) { ALL_OBJFILE_PSYMTABS (objfile, pst) { if (save_pst != pst ! && TEXTLOW (save_pst) >= TEXTLOW (pst) ! && TEXTLOW (save_pst) < TEXTHIGH (pst) ! && TEXTHIGH (save_pst) > TEXTHIGH (pst)) { objfile->flags |= OBJF_REORDERED; break; *************** *** 3252,3258 **** /* Do nothing if this is a dummy psymtab. */ if (pst->n_global_syms == 0 && pst->n_static_syms == 0 ! && pst->textlow == 0 && pst->texthigh == 0) return; /* Now read the symbols for this symtab */ --- 3274,3280 ---- /* Do nothing if this is a dummy psymtab. */ if (pst->n_global_syms == 0 && pst->n_static_syms == 0 ! && TEXTLOW (pst) == 0 && TEXTHIGH (pst) == 0) return; /* Now read the symbols for this symtab */ *************** *** 3400,3406 **** if (! last_symtab_ended) { ! st = end_symtab (pst->texthigh, pst->objfile, SECT_OFF_TEXT (pst->objfile)); end_stabs (); } --- 3422,3428 ---- if (! last_symtab_ended) { ! st = end_symtab (TEXTHIGH (pst), pst->objfile, SECT_OFF_TEXT (pst->objfile)); end_stabs (); } *************** *** 3490,3496 **** top_stack->cur_st = st; top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (st), STATIC_BLOCK); ! BLOCK_START (top_stack->cur_block) = pst->textlow; BLOCK_END (top_stack->cur_block) = 0; top_stack->blocktype = stFile; top_stack->maxsyms = 2 * f_max; --- 3512,3518 ---- top_stack->cur_st = st; top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (st), STATIC_BLOCK); ! BLOCK_START (top_stack->cur_block) = TEXTLOW (pst); BLOCK_END (top_stack->cur_block) = 0; top_stack->blocktype = stFile; top_stack->maxsyms = 2 * f_max; Index: gdb/partial-stab.h =================================================================== RCS file: /cvs/src/src/gdb/partial-stab.h,v retrieving revision 1.13 diff -c -r1.13 partial-stab.h *** gdb/partial-stab.h 2001/09/06 20:50:48 1.13 --- gdb/partial-stab.h 2001/10/23 23:14:42 *************** *** 104,115 **** if (past_first_source_file && pst /* The gould NP1 uses low values for .o and -l symbols which are not the address. */ ! && CUR_SYMBOL_VALUE >= pst->textlow) { END_PSYMTAB (pst, psymtab_include_list, includes_used, symnum * symbol_size, ! CUR_SYMBOL_VALUE > pst->texthigh ! ? CUR_SYMBOL_VALUE : pst->texthigh, dependency_list, dependencies_used, textlow_not_set); pst = (struct partial_symtab *) 0; includes_used = 0; --- 104,115 ---- if (past_first_source_file && pst /* The gould NP1 uses low values for .o and -l symbols which are not the address. */ ! && CUR_SYMBOL_VALUE >= TEXTLOW (pst)) { END_PSYMTAB (pst, psymtab_include_list, includes_used, symnum * symbol_size, ! CUR_SYMBOL_VALUE > TEXTHIGH (pst) ! ? CUR_SYMBOL_VALUE : TEXTHIGH (pst), dependency_list, dependencies_used, textlow_not_set); pst = (struct partial_symtab *) 0; includes_used = 0; *************** *** 236,242 **** { END_PSYMTAB (pst, psymtab_include_list, includes_used, symnum * symbol_size, ! valu > pst->texthigh ? valu : pst->texthigh, dependency_list, dependencies_used, prev_textlow_not_set); pst = (struct partial_symtab *) 0; --- 236,242 ---- { END_PSYMTAB (pst, psymtab_include_list, includes_used, symnum * symbol_size, ! valu > TEXTHIGH (pst) ? valu : TEXTHIGH (pst), dependency_list, dependencies_used, prev_textlow_not_set); pst = (struct partial_symtab *) 0; *************** *** 405,412 **** function relative stabs, or the address of the function's end for old style stabs. */ valu = CUR_SYMBOL_VALUE + last_function_start; ! if (pst->texthigh == 0 || valu > pst->texthigh) ! pst->texthigh = valu; break; } #endif --- 405,412 ---- function relative stabs, or the address of the function's end for old style stabs. */ valu = CUR_SYMBOL_VALUE + last_function_start; ! if (TEXTHIGH (pst) == 0 || valu > TEXTHIGH (pst)) ! TEXTHIGH (pst) = valu; break; } #endif *************** *** 610,616 **** } if (pst && textlow_not_set) { ! pst->textlow = CUR_SYMBOL_VALUE; textlow_not_set = 0; } #endif --- 610,616 ---- } if (pst && textlow_not_set) { ! TEXTLOW (pst) = CUR_SYMBOL_VALUE; textlow_not_set = 0; } #endif *************** *** 626,637 **** the partial symbol table. */ if (pst && (textlow_not_set ! || (CUR_SYMBOL_VALUE < pst->textlow && (CUR_SYMBOL_VALUE != ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))))) { ! pst->textlow = CUR_SYMBOL_VALUE; textlow_not_set = 0; } #endif /* DBXREAD_ONLY */ --- 626,637 ---- the partial symbol table. */ if (pst && (textlow_not_set ! || (CUR_SYMBOL_VALUE < TEXTLOW (pst) && (CUR_SYMBOL_VALUE != ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))))) { ! TEXTLOW (pst) = CUR_SYMBOL_VALUE; textlow_not_set = 0; } #endif /* DBXREAD_ONLY */ *************** *** 677,683 **** } if (pst && textlow_not_set) { ! pst->textlow = CUR_SYMBOL_VALUE; textlow_not_set = 0; } #endif --- 677,683 ---- } if (pst && textlow_not_set) { ! TEXTLOW (pst) = CUR_SYMBOL_VALUE; textlow_not_set = 0; } #endif *************** *** 693,704 **** the partial symbol table. */ if (pst && (textlow_not_set ! || (CUR_SYMBOL_VALUE < pst->textlow && (CUR_SYMBOL_VALUE != ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))))) { ! pst->textlow = CUR_SYMBOL_VALUE; textlow_not_set = 0; } #endif /* DBXREAD_ONLY */ --- 693,704 ---- the partial symbol table. */ if (pst && (textlow_not_set ! || (CUR_SYMBOL_VALUE < TEXTLOW (pst) && (CUR_SYMBOL_VALUE != ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))))) { ! TEXTLOW (pst) = CUR_SYMBOL_VALUE; textlow_not_set = 0; } #endif /* DBXREAD_ONLY */ *************** *** 813,819 **** case N_ENDM: #ifdef SOFUN_ADDRESS_MAYBE_MISSING /* Solaris 2 end of module, finish current partial symbol table. ! END_PSYMTAB will set pst->texthigh to the proper value, which is necessary if a module compiled without debugging info follows this module. */ if (pst) --- 813,819 ---- case N_ENDM: #ifdef SOFUN_ADDRESS_MAYBE_MISSING /* Solaris 2 end of module, finish current partial symbol table. ! END_PSYMTAB will set TEXTHIGH (pst) to the proper value, which is necessary if a module compiled without debugging info follows this module. */ if (pst)