On 2018-05-04 17:03, Ralf Ramsauer wrote: > > > On 05/04/2018 04:08 PM, Jan Kiszka wrote: >> On 2018-05-04 15:44, Ralf Ramsauer wrote: >>> >>> >>> On 05/04/2018 12:57 PM, Ralf Ramsauer wrote: >>>> >>>> >>>> On 05/04/2018 12:38 PM, Jan Kiszka wrote: >>>>> On 2018-05-04 11:12, Ralf Ramsauer wrote: >>>>>> On 05/02/2018 06:18 PM, Jan Kiszka wrote: >>>>>>> On 2018-05-02 16:51, Ralf Ramsauer wrote: >>>>>>>> >>>>>>>> >>>>>>>> On 05/01/2018 06:54 PM, Jan Kiszka wrote: >>>>>>>>> On 2018-05-01 10:54, Ralf Ramsauer wrote: >>>>>>>>>> On 04/27/2018 08:21 PM, Jan Kiszka wrote: >>>>>>>>>>> On 2018-04-27 11:36, Ralf Ramsauer wrote: >>>>>>>>>>>> This won't drop symbols that are marked as used. >>>>>>>>>>>> >>>>>>>>>>>> The static, relocateable inmate library lib.a is created by ar. >>>>>>>>>>>> When >>>>>>>>>>>> linking executables, unreferenced symbols may be dropped, even if >>>>>>>>>>>> they >>>>>>>>>>>> are attributed as used. >>>>>>>>>>>> >>>>>>>>>>>> --whole-archive ensures that those symbols will be linked. >>>>>>>>>>>> >>>>>>>>>>>> Whereas on x86, we need --gc-sections. >>>>>>>>>>> >>>>>>>>>>> That's something I do not understand yet: With [1] we will build the >>>>>>>>>>> whole hypervisor, including x86, with --whole-archive, and that >>>>>>>>>>> works >>>>>>>>>>> fine on x86 as well. >>>>>>>>>> >>>>>>>>>> That's what happens if I compile x86 inmates with --whole-archive >>>>>>>>>> instead of --gc-sections: >>>>>>>>>> >>>>>>>>>> LD >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/demos/x86/32-bit-demo-linked.o >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/lib32.a(ioapic-32.o): >>>>>>>>>> In >>>>>>>>>> function `ioapic_init': >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/ioapic.c:48: undefined >>>>>>>>>> reference to `map_range' >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/lib32.a(smp-32.o): In >>>>>>>>>> function `smp_start_cpu': >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/smp.c:59: undefined >>>>>>>>>> reference to `delay_us' >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/smp.c:61: undefined >>>>>>>>>> reference to `delay_us' >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/lib32.a(pci-32.o): In >>>>>>>>>> function `pci_find_device': >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/../pci.c:47: undefined >>>>>>>>>> reference to `pci_read_config' >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/../pci.c:51: undefined >>>>>>>>>> reference to `pci_read_config' >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/lib32.a(pci-32.o): In >>>>>>>>>> function `pci_find_cap': >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/../pci.c:61: undefined >>>>>>>>>> reference to `pci_read_config' >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/../pci.c:65: undefined >>>>>>>>>> reference to `pci_read_config' >>>>>>>>>> /home/ralf/workspace/jailhouse/inmates/lib/x86/../pci.c:68: undefined >>>>>>>>>> reference to `pci_read_config' >>>>>>>>>> >>>>>>>>>> Interestingly, this only happens to the 32-bit demo inmate. >>>>>>>>>> >>>>>>>>> >>>>>>>>> Because we keep everything, something might be missing now: The 32-bit >>>>>>>>> lib does not provide support for all features that its big 64-bit >>>>>>>>> brother has. >>>>>>>>> >>>>>>>>> I still think this approach is too much of a big hammer. Try >>>>>>>>> --print-gc-sections on your specific problem (uart section loss) and >>>>>>>>> play with --undefined as suggested by the ld man page. Not sure if >>>>>>>>> there >>>>>>>>> is also some linker script statement that can do that trick, but it >>>>>>>>> might be worth checking. >>>>>>>> >>>>>>>> KEEP, together with --whole-archive does the trick: >>>>>>>> >>>>>>> >>>>>>> Why still --whole-archive? We should have a clear reason here. >>>>>> >>>>>> Doesn't work without --whole-archive, ld still drops it then. It's the >>>>>> combination of --whole-archive and KEEP() that makes it working for ARM >>>>>> on the one hand, and doesn't break the 32-bit x86 demo inmate on the >>>>>> other. >>>>>> >>>>>> I guess the reason is that KEEP() only keeps symbols that enter a 'final >>>>>> stage' of the linking process. And as those symbols are never referenced >>>>>> anywhere, they seem to be dropped before, like they never enter that >>>>>> stage of the process where they could be kept. >>>>> >>>>> Should be possible to confirm this: We have records of all stages (*.o, >>>>> *.a). >>>>> >>>>>> >>>>>> See [1], 4.6.4.4: >>>>>> When link-time garbage collection is in use (-gc-sections), it is >>>>>> often useful to mark sections that should not be eliminated. This is >>>>>> accomplished by surrounding an input section's wildcard entry with >>>>>> KEEP(), as in KEEP(*(.init)) or KEEP(SORT(*)(.ctors)). >>>>> >>>>> I'm wondering the following: >>>>> >>>>> - Is "--whole-archive --gc-sections" a reasonable combination (it >>>>> sounds contradictory), or does this just happen to work and will break >>>>> again with a different compiler version or some tuning elsewhere? >>> >>> Looks like a dead end at the moment, but at least I understand what's >>> going on: >>> >>> When linking, ld searches for the ENTRY point, and recursively looks up >>> referenced symbols until there are no more undef'd refs. [1] >>> >>> So if, e.g., gic_init() is found in gic.o which is embedded in lib.a, >>> then ld will include _all_ symbols from gic.o and later garbage collect >>> undef'd ones. >>> >>> In above case, symbols in uart drivers (e.g. uart_8250.o which is also >>> inside lib.a) are referenced nowhere, so the whole object file will >>> _never_ be considered for linking, even if there is a KEEP() around the >>> section. KEEP() only respects symbols that the linker has seen, but it >>> never has seen any symbol of uart_8250.o . >>> >>> I can confirm this behavior by testing: If I introduce a global int >>> foobar = 42; to uart-8250.c and reference foobar from uart-demo.c, then >>> suddenly the .uarts section from uart-8250.c will be linked, as the >>> object file is now considered for linking. >>> >> >> That's possibly where these could come into play: >> >> -u symbol >> --undefined=symbol >> Force symbol to be entered in the output file as an undefined >> symbol. Doing this may, for example, trigger linking of >> additional modules from standard libraries. -u may be >> repeated with different option arguments to enter additional >> undefined symbols. This option is equivalent to the "EXTERN" >> linker script command. >> >> If this option is being used to force additional modules to >> be pulled into the link, and if it is an error for the symbol >> to remain undefined, then the option --require-defined should >> be used instead. >> >> --require-defined=symbol >> Require that symbol is defined in the output file. This >> option is the same as option --undefined except that if >> symbol is not defined in the output file then the linker will >> issue an error and exit. The same effect can be achieved in >> a linker script by using "EXTERN", "ASSERT" and "DEFINED" >> together. This option can be used multiple times to require >> additional symbols. > > Yes, this works, but I need to specify every single symbol that I want > to link, there's no wildcard functionality (at least no documented one). >
That is surely not how things should work. I wonder if/how the ctor/dtor stuff is handled in --gc-sections setups. Anyway. > I mean you don't want to touch the linker file every time someone adds > an UART driver. Happy debugging if someone forgets the pinning in the > linker file. ;-) > > So this should definitely be somehow automated, if this is really the > solution. > > There i see two ways how to accomplish that: > - Let the DEFINE_UART() macro emit EXTERN(symbol_name), on > #if __ASSEMBLY__ and somehow include uart driver sources when > preprocessing inmate.lds.S > > - Do some Makefile magic and define uart driver object names in an own > variable. Append that variable to objs-y, and substitute the name > and pass the --undefined arguments to LDFLAGS. > This requires the basename of the driver source file to be the same > as the basename of the symbol (which currently is the case as far as > i see) > > Other suggestions? Both solutions are ugly, but defining symbols names > manually is unhandsome as well. > > Puh, that patch series really exploded in complexity, didn't expect > that. Just wanted to implement poor man's dynamic hardware configuration > for ARM inmates which in the end will really help me with my psci > patches. Then I ended up with cache coherence issues and deep linker > internals... Well, the cache coherence thing was surely a very important result as it also affects ivshmem. Maybe we can push the DEFINE_UART topic to the back of the queue and "play" with that again when the other issues are resolved. Thanks in any case! Jan -- Siemens AG, Corporate Technology, CT RDA IOT SES-DE Corporate Competence Center Embedded Linux -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
