Date: Sun, 4 Jan 2015 19:22:46 +1100 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Justin Hibbits <jhibbits@freebsd.org> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r276652 - head/sys/powerpc/include Message-ID: <20150104175630.N938@besplex.bde.org> In-Reply-To: <201501040145.t041jR6v002901@svn.freebsd.org> References: <201501040145.t041jR6v002901@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 4 Jan 2015, Justin Hibbits wrote: > Log: > Truncate DB_SMALL_VALUE_MAX to a much lower value. > > Unlike the other architectures, the PowerPC kernel is loaded under the 2GB > boundary. > > MFC after: 2 weeks > > Modified: > head/sys/powerpc/include/db_machdep.h > > Modified: head/sys/powerpc/include/db_machdep.h > ============================================================================== > --- head/sys/powerpc/include/db_machdep.h Sun Jan 4 00:58:30 2015 (r276651) > +++ head/sys/powerpc/include/db_machdep.h Sun Jan 4 01:45:26 2015 (r276652) > @@ -87,7 +87,7 @@ typedef intptr_t db_expr_t; /* expressio > #define inst_load(ins) 0 > #define inst_store(ins) 0 > > -#define DB_SMALL_VALUE_MAX (0x7fffffff) > +#define DB_SMALL_VALUE_MAX (KERNBASE-1) > #define DB_SMALL_VALUE_MIN (-0x40001) > > #endif /* _POWERPC_DB_MACHDEP_H_ */ DB_SMALL_VALUE was broken on all arches AFAIK. Hopefully it now sort of works for PowerPC, and you can fix it better for PowerPC and then other arches. It was first implemented in: X RCS file: /home/ncvs/src/sys/ddb/db_sym.c,v X Working file: db_sym.c X head: 1.35 X ... X ---------------------------- X revision 1.17 X date: 1997/01/16 11:27:10; author: bde; state: Exp; lines: +8 -2 X Fixed printing of small offsets. E.g., -4(%ebp) is now printed X as -0x4(%ebp) instead of as _APTD+0xffc(%ebp), and if GUPROF is X defined, 8(%ebp) is now printed as 0x8(%ebp) instead of as X GMON_PROF_HIRES+0x4(%ebp). X ---------------------------- This depends on magic symbols like _APTD. Someone broke this on i386 by removing these magic symbols without updating the definition of DB_SMALL_VALUE_MAX. Other arches are even more broken. They never had a suitable magic symbol and/or the i386 value was copied without changing it except to expand to 64 bits. The brokenness is especially large on 64-bit arches. It causes small negative offsets from the stack or frame pointer to be misclassified as large, so they are printed as huge cryptic unsigned values instead of as small signed values. E.g., -24(%ebp) is printed as 0xffffffe8(%ebp) on i386 and -24(%rbp) is printed as 0xffffffffffffffe8(%ebp) on amd64. I use the following quick fixes for i386: X Index: db_sym.c X =================================================================== X RCS file: /home/ncvs/src/sys/ddb/db_sym.c,v X retrieving revision 1.35 X diff -u -2 -r1.35 db_sym.c X --- db_sym.c 24 Feb 2004 22:51:42 -0000 1.35 X +++ db_sym.c 25 Feb 2004 10:11:09 -0000 X @@ -303,5 +303,9 @@ X if (name == 0) X value = off; X +#ifdef magic_large_symbols_unbroken X if (value >= DB_SMALL_VALUE_MIN && value <= DB_SMALL_VALUE_MAX) { X +#else X + if (off >= DB_SMALL_VALUE_MIN && off <= DB_SMALL_VALUE_MAX) { X +#endif X db_printf("%+#lr", (long)off); X return; X Index: db_machdep.h X =================================================================== X RCS file: /home/ncvs/src/sys/i386/include/db_machdep.h,v X retrieving revision 1.17 X diff -u -2 -r1.17 db_machdep.h X --- db_machdep.h 15 Sep 2001 11:06:07 -0000 1.17 X +++ db_machdep.h 9 Nov 2003 15:54:26 -0000 X @@ -87,7 +87,9 @@ X * _APTmap = 0xffc00000. Accepting this is OK (unless db_maxoff is X * set to >= 0x400000 - (max stack offset)). X + * XXX _APTD and _APTmap went away. Now there are SMP_prvspace = 0xffc00000 X + * and lapic = 0xfffff000. X */ X #define DB_SMALL_VALUE_MAX 0x7fffffff X -#define DB_SMALL_VALUE_MIN (-0x400001) X +#define DB_SMALL_VALUE_MIN (-0x3fffff) X X #endif /* !_MACHINE_DB_MACHDEP_H_ */ I forget why I changed the logic in db_sym.c. It is only a heuristic. DB_SMALL_VALUE_MAX should probably be related to KERNBASE on all arches, or just be much smaller. 0x7fffffff obviously doesn't work on i386 either if KERNBASE is smaller than that. Namespace problems prevent defining the DB* symbols in terms of KERNBASE and even more so for symbols like _APTD that were only defined in object files. 0x7fffffff allowed reduction of KERNBASE well below its default value at the time of the original implementation. It was only about 32MB or 256MB below the top. Now its default is 3GB and 2GB isn't much lower, but it is not very useful on i386 to change the split to much more for the kernel and much less for applications. DB_SMALL_VALUE_MIN is related to the memory layout. There may be symbols near the top of the address space no matter what KERNBASE is. This happens on i386 -- most kernel symbols are near KERNBASE (default 0xc0000000) but there are some magic symbols related mainly to page tables near the top. We want to print all of these symbols by name, or at least as large unsigned values (the latter happens too much for constant literals in ddb and gdb, and objdump is worse). So DB_SMALL_VALUE_MIN must be fairly small. Also, the address space should be laid out so as to not have any important symbols near the top, to leave space for DB_SMALL_VALUE_MIN not needing to be too small. To avoid the namespace bugs and to de-magic the limits, the definitions show be something like: /* Set in locore; currently only used in ldscript: */ extern char kernbase[]; /* If not already defined somwhere: */ extern char end[]; #define DB_SMALL_VALUE_MAX kernbase #define DB_SMALL_VALUE_MIN (-(intptr_t)end) /* does this work? */ Or with less magic: /* Set these in locore like kernbase: */ extern char db_smallest_ksym[]; extern char db_largest_ksym[]; #define DB_SMALL_VALUE_MAX db_smallest_ksym #define DB_SMALL_VALUE_MIN (-(intptr_t)db_largest_ksym) It is difficult to define the magic symbols with best values to work with the heuristic even when you control them. Addresses outside of the statically known address space may be generated by loading modules and malloc()ing data. These shouldn't be printed as signed. The above definitions give too wide a range of small values. So db_largest_ksym should be set to something more like its current value of a few MB below the top, perhaps to max(this value, end). I don't know how to write this expression in asm. It could be written in C: #define DB_SMALL_VALUE_MIN MAX(-3xfffff, -(intptr_t)db_largest_ksym) db_largest_ksym must also be larger than INTPTR_MAX for the sign magic to work. That probably won't happen automatically if all static kernel symbols are in the lower half of the address space. The i386 kernel address space now looks like: X 00400000 A kernload X bfc00000 A PTmap X bfeff000 A PTD X bfeffbfc A PTDpde X c0000000 A kernbase X c0453fd0 T btext X c0454039 t begin X ... X c092f494 A _end X c092f494 A end This hasn't changed for more than 10 years. Apparently the page table stuff was moved from the top of the address space to just below kernbase, so there are no symbols near the top. DB_SMALL_VALUE_MAX needs to be below kernbase. The low kernload symbol might be a problem. The amd64 address space now looks like: X w uart_sab82532_class X w uart_z8530_class No values? X 0000000000200000 A kernphys X ffff800000000000 A loc_PTmap X ffff804000000000 A loc_PDmap X ffff804020000000 A loc_PDPmap X ffff804020100000 A loc_PML4map X ffff804020100800 A loc_PML4pml4e X fffff80000000000 A dmapbase X fffffc0000000000 A dmapend X ffffffff80000000 A kernbase X ffffffff802baa50 T btext X ... X ffffffff8123be08 A _end Essentially the same. The smallest symbol of interest is much further below kernbase, and I think malloced memory is below kernbase too (there is only 2GB above). Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150104175630.N938>