[libunwind] r332512 - [OR1K] Add a dedicated PC register to register state.
Author: whitequark Date: Wed May 16 12:09:41 2018 New Revision: 332512 URL: http://llvm.org/viewvc/llvm-project?rev=332512&view=rev Log: [OR1K] Add a dedicated PC register to register state. Before this commit, R9, the link register, was used as PC register. However, a stack frame may have R9 not set to PC on entry, either because it uses a custom calling convention, or, more likely, because this is a signal or exception stack frame. Using R9 as PC register made it impossible to unwind such frames. All other architectures similarly use a dedicated PC register. Modified: libunwind/trunk/src/Registers.hpp libunwind/trunk/src/UnwindRegistersRestore.S libunwind/trunk/src/UnwindRegistersSave.S Modified: libunwind/trunk/src/Registers.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/Registers.hpp?rev=332512&r1=332511&r2=332512&view=diff == --- libunwind/trunk/src/Registers.hpp (original) +++ libunwind/trunk/src/Registers.hpp Wed May 16 12:09:41 2018 @@ -2521,12 +2521,13 @@ public: uint64_t getSP() const { return _registers.__r[1]; } void setSP(uint32_t value) { _registers.__r[1] = value; } - uint64_t getIP() const { return _registers.__r[9]; } - void setIP(uint32_t value) { _registers.__r[9] = value; } + uint64_t getIP() const { return _registers.__pc; } + void setIP(uint32_t value) { _registers.__pc = value; } private: struct or1k_thread_state_t { -unsigned int __r[32]; +unsigned int __r[32]; // r0-r31 +unsigned int __pc;// Program counter }; or1k_thread_state_t _registers; @@ -2561,7 +2562,7 @@ inline uint32_t Registers_or1k::getRegis switch (regNum) { case UNW_REG_IP: -return _registers.__r[9]; +return _registers.__pc; case UNW_REG_SP: return _registers.__r[1]; } @@ -2576,7 +2577,7 @@ inline void Registers_or1k::setRegister( switch (regNum) { case UNW_REG_IP: -_registers.__r[9] = value; +_registers.__pc = value; return; case UNW_REG_SP: _registers.__r[1] = value; Modified: libunwind/trunk/src/UnwindRegistersRestore.S URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersRestore.S?rev=332512&r1=332511&r2=332512&view=diff == --- libunwind/trunk/src/UnwindRegistersRestore.S (original) +++ libunwind/trunk/src/UnwindRegistersRestore.S Wed May 16 12:09:41 2018 @@ -758,7 +758,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li # thread_state pointer is in r3 # - # restore integral registerrs + # restore integral registers l.lwz r0, 0(r3) l.lwz r1, 4(r3) l.lwz r2, 8(r3) @@ -768,7 +768,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li l.lwz r6, 24(r3) l.lwz r7, 28(r3) l.lwz r8, 32(r3) - l.lwz r9, 36(r3) + # skip r9 l.lwzr10, 40(r3) l.lwzr11, 44(r3) l.lwzr12, 48(r3) @@ -795,6 +795,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li # at last, restore r3 l.lwzr3, 12(r3) + # load new pc into ra + l.lwzr9, 128(r3) # jump to pc l.jr r9 l.nop Modified: libunwind/trunk/src/UnwindRegistersSave.S URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersSave.S?rev=332512&r1=332511&r2=332512&view=diff == --- libunwind/trunk/src/UnwindRegistersSave.S (original) +++ libunwind/trunk/src/UnwindRegistersSave.S Wed May 16 12:09:41 2018 @@ -938,6 +938,8 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext l.sw 116(r3), r29 l.sw 120(r3), r30 l.sw 124(r3), r31 + # store ra to pc + l.sw 128(r3), r9 #endif #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] r332513 - [OR1K] Add the EPCR special-purpose register to register state.
Author: whitequark Date: Wed May 16 12:09:48 2018 New Revision: 332513 URL: http://llvm.org/viewvc/llvm-project?rev=332513&view=rev Log: [OR1K] Add the EPCR special-purpose register to register state. This makes it possible to unwind hardware exception stack frames, which necessarily save every register and so need an extra column for storing the return address. CFI for the exception handler could then look as follows: .globl exception_vector exception_vector: .cfi_startproc .cfi_signal_frame .cfi_return_column 32 l.addi r1, r1, -0x100 .cfi_def_cfa_offset 0x100 l.sw0x00(r1), r2 .cfi_offset 2, 0x00-0x100 l.sw0x04(r1), r3 .cfi_offset 3, 0x04-0x100 l.sw0x08(r1), r4 .cfi_offset 4, 0x08-0x100 l.mfspr r3, r0, SPR_EPCR_BASE l.sw0x78(r1), r3 .cfi_offset 32, 0x78-0x100 l.jal exception_handler l.nop l.lwz r2, 0x00(r1) l.lwz r3, 0x04(r1) l.lwz r4, 0x08(r1) l.jrr9 l.nop .cfi_endproc This register could, of course, also be accessed by the trace callback or personality function, if so desired. Modified: libunwind/trunk/include/__libunwind_config.h libunwind/trunk/include/libunwind.h libunwind/trunk/src/Registers.hpp libunwind/trunk/src/UnwindRegistersSave.S Modified: libunwind/trunk/include/__libunwind_config.h URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/__libunwind_config.h?rev=332513&r1=332512&r2=332513&view=diff == --- libunwind/trunk/include/__libunwind_config.h (original) +++ libunwind/trunk/include/__libunwind_config.h Wed May 16 12:09:48 2018 @@ -21,7 +21,7 @@ #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64 116 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 95 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM 287 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 31 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65 #if defined(_LIBUNWIND_IS_NATIVE_ONLY) Modified: libunwind/trunk/include/libunwind.h URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/libunwind.h?rev=332513&r1=332512&r2=332513&view=diff == --- libunwind/trunk/include/libunwind.h (original) +++ libunwind/trunk/include/libunwind.h Wed May 16 12:09:48 2018 @@ -745,6 +745,7 @@ enum { UNW_OR1K_R29 = 29, UNW_OR1K_R30 = 30, UNW_OR1K_R31 = 31, + UNW_OR1K_EPCR = 32, }; // MIPS registers Modified: libunwind/trunk/src/Registers.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/Registers.hpp?rev=332513&r1=332512&r2=332513&view=diff == --- libunwind/trunk/src/Registers.hpp (original) +++ libunwind/trunk/src/Registers.hpp Wed May 16 12:09:48 2018 @@ -2528,6 +2528,7 @@ private: struct or1k_thread_state_t { unsigned int __r[32]; // r0-r31 unsigned int __pc;// Program counter +unsigned int __epcr; // Program counter at exception }; or1k_thread_state_t _registers; @@ -2553,6 +2554,8 @@ inline bool Registers_or1k::validRegiste return false; if (regNum <= UNW_OR1K_R31) return true; + if (regNum == UNW_OR1K_EPCR) +return true; return false; } @@ -2565,6 +2568,8 @@ inline uint32_t Registers_or1k::getRegis return _registers.__pc; case UNW_REG_SP: return _registers.__r[1]; + case UNW_OR1K_EPCR: +return _registers.__epcr; } _LIBUNWIND_ABORT("unsupported or1k register"); } @@ -2582,6 +2587,9 @@ inline void Registers_or1k::setRegister( case UNW_REG_SP: _registers.__r[1] = value; return; + case UNW_OR1K_EPCR: +_registers.__epcr = value; +return; } _LIBUNWIND_ABORT("unsupported or1k register"); } @@ -2677,6 +2685,8 @@ inline const char *Registers_or1k::getRe return "r30"; case UNW_OR1K_R31: return "r31"; + case UNW_OR1K_EPCR: +return "EPCR"; default: return "unknown register"; } Modified: libunwind/trunk/src/UnwindRegistersSave.S URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersSave.S?rev=332513&r1=332512&r2=332513&view=diff == --- libunwind/trunk/src/UnwindRegistersSave.S (original) +++ libunwind/trunk/src/UnwindRegistersSave.S Wed May 16 12:09:48 2018 @@ -940,6 +940,8 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext l.sw 124(r3), r31 # store ra to pc l.sw 128(r3), r9 + # zero epcr + l.sw 132(r3), r0 #endif #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] r321440 - [libunwind] Avoid using C++ headers.
Author: whitequark Date: Mon Dec 25 05:06:09 2017 New Revision: 321440 URL: http://llvm.org/viewvc/llvm-project?rev=321440&view=rev Log: [libunwind] Avoid using C++ headers. This is useful for building libunwind on libcxx-free systems. Modified: libunwind/trunk/src/DwarfParser.hpp Modified: libunwind/trunk/src/DwarfParser.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=321440&r1=321439&r2=321440&view=diff == --- libunwind/trunk/src/DwarfParser.hpp (original) +++ libunwind/trunk/src/DwarfParser.hpp Mon Dec 25 05:06:09 2017 @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include "libunwind.h" #include "dwarf2.h" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] r321441 - [libunwind] convert error logs to _LIBUNWIND_LOG/_LIBUNWIND_LOG0.
Author: whitequark Date: Mon Dec 25 05:27:56 2017 New Revision: 321441 URL: http://llvm.org/viewvc/llvm-project?rev=321441&view=rev Log: [libunwind] convert error logs to _LIBUNWIND_LOG/_LIBUNWIND_LOG0. Use the `_LIBUNWIND_LOG` and `_LIBUNWIND_LOG0` macros instead of the explicit `fprintf` call. This was previously done in r292721 as a cleanup and then reverted in r293257 because the implementation in r292721 relied on a GNU extension. This implementation avoids the use of an extension by using a second macro instead, and allows to avoid the dependency on fprintf if _LIBUNWIND_BARE_METAL is defined. Modified: libunwind/trunk/src/DwarfParser.hpp libunwind/trunk/src/config.h Modified: libunwind/trunk/src/DwarfParser.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=321441&r1=321440&r2=321441&view=diff == --- libunwind/trunk/src/DwarfParser.hpp (original) +++ libunwind/trunk/src/DwarfParser.hpp Mon Dec 25 05:27:56 2017 @@ -416,8 +416,8 @@ bool CFI_Parser::parseInstructions(A offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; if (reg > kMaxRegisterNumber) { -fprintf(stderr, -"malformed DW_CFA_offset_extended DWARF unwind, reg too big\n"); +_LIBUNWIND_LOG0( +"malformed DW_CFA_offset_extended DWARF unwind, reg too big"); return false; } results->savedRegisters[reg].location = kRegisterInCFA; @@ -429,9 +429,8 @@ bool CFI_Parser::parseInstructions(A case DW_CFA_restore_extended: reg = addressSpace.getULEB128(p, instructionsEnd); if (reg > kMaxRegisterNumber) { -fprintf( -stderr, -"malformed DW_CFA_restore_extended DWARF unwind, reg too big\n"); +_LIBUNWIND_LOG0( +"malformed DW_CFA_restore_extended DWARF unwind, reg too big"); return false; } results->savedRegisters[reg] = initialState.savedRegisters[reg]; @@ -440,8 +439,8 @@ bool CFI_Parser::parseInstructions(A case DW_CFA_undefined: reg = addressSpace.getULEB128(p, instructionsEnd); if (reg > kMaxRegisterNumber) { -fprintf(stderr, -"malformed DW_CFA_undefined DWARF unwind, reg too big\n"); +_LIBUNWIND_LOG0( +"malformed DW_CFA_undefined DWARF unwind, reg too big"); return false; } results->savedRegisters[reg].location = kRegisterUnused; @@ -450,8 +449,8 @@ bool CFI_Parser::parseInstructions(A case DW_CFA_same_value: reg = addressSpace.getULEB128(p, instructionsEnd); if (reg > kMaxRegisterNumber) { -fprintf(stderr, -"malformed DW_CFA_same_value DWARF unwind, reg too big\n"); +_LIBUNWIND_LOG0( +"malformed DW_CFA_same_value DWARF unwind, reg too big"); return false; } // DW_CFA_same_value unsupported @@ -467,13 +466,13 @@ bool CFI_Parser::parseInstructions(A reg = addressSpace.getULEB128(p, instructionsEnd); reg2 = addressSpace.getULEB128(p, instructionsEnd); if (reg > kMaxRegisterNumber) { -fprintf(stderr, -"malformed DW_CFA_register DWARF unwind, reg too big\n"); +_LIBUNWIND_LOG0( +"malformed DW_CFA_register DWARF unwind, reg too big"); return false; } if (reg2 > kMaxRegisterNumber) { -fprintf(stderr, -"malformed DW_CFA_register DWARF unwind, reg2 too big\n"); +_LIBUNWIND_LOG0( +"malformed DW_CFA_register DWARF unwind, reg2 too big"); return false; } results->savedRegisters[reg].location = kRegisterInRegister; @@ -512,7 +511,7 @@ bool CFI_Parser::parseInstructions(A reg = addressSpace.getULEB128(p, instructionsEnd); offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd); if (reg > kMaxRegisterNumber) { -fprintf(stderr, "malformed DW_CFA_def_cfa DWARF unwind, reg too big\n"); +_LIBUNWIND_LOG0("malformed DW_CFA_def_cfa DWARF unwind, reg too big"); return false; } results->cfaRegister = (uint32_t)reg; @@ -523,9 +522,8 @@ bool CFI_Parser::parseInstructions(A case DW_CFA_def_cfa_register: reg = addressSpace.getULEB128(p, instructionsEnd); if (reg > kMaxRegisterNumber) { -fprintf( -stderr, -"malformed DW_CFA_def_cfa_register DWARF unwind, reg too big\n"); +_LIBUNWIND_LOG0( +"malformed DW_CFA_def_cfa_register DWARF unwind, reg too big"); return false; } results->cfaRegister = (uint32_t)reg; @@ -551,8 +549,8 @@ bool CFI_Parser::parseInstructions(A case DW_CFA_expression: reg = addressSpace.getULEB128(p, instructionsEnd); if (reg > kMaxRegisterNumber) { -fprintf(st
[libunwind] r321442 - [libunwind] fix a typo in r321441.
Author: whitequark Date: Mon Dec 25 05:42:41 2017 New Revision: 321442 URL: http://llvm.org/viewvc/llvm-project?rev=321442&view=rev Log: [libunwind] fix a typo in r321441. Modified: libunwind/trunk/src/DwarfParser.hpp Modified: libunwind/trunk/src/DwarfParser.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=321442&r1=321441&r2=321442&view=diff == --- libunwind/trunk/src/DwarfParser.hpp (original) +++ libunwind/trunk/src/DwarfParser.hpp Mon Dec 25 05:42:41 2017 @@ -549,7 +549,7 @@ bool CFI_Parser::parseInstructions(A case DW_CFA_expression: reg = addressSpace.getULEB128(p, instructionsEnd); if (reg > kMaxRegisterNumber) { -_LIBUNWIND_LOG( +_LIBUNWIND_LOG0( "malformed DW_CFA_expression DWARF unwind, reg too big"); return false; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] r321445 - [libunwind] Add proper support for DWARF unwind on bare metal.
Author: whitequark Date: Mon Dec 25 09:05:07 2017 New Revision: 321445 URL: http://llvm.org/viewvc/llvm-project?rev=321445&view=rev Log: [libunwind] Add proper support for DWARF unwind on bare metal. Right now, ARM EHABI unwind on bare metal expects to find the symbols __exidx_start and __exidx_end defined, and uses those to locate the EH tables. However, DWARF unwind on bare metal expects to find dl_iterate_phdr, which, although possible to provide, is inconvenient and mildly absurd. This commit provides feature parity with ARM EHABI unwind by looking for symbols __eh_frame_start, __eh_frame_end, __eh_frame_hdr_start and __eh_frame_hdr_end, denoting the start and end of the sections with corresponding names. As far as I know, there is no de jure or de facto ABI providing any such names, so I chose the obvious ones. The .eh_frame_hdr support is optional for maximum flexibility and possible space savings (e.g. if libunwind is only used to provide backtraces when a device crashes, providing the .eh_frame_hdr, which is an index for rapid access to EH tables, would be a waste.) The support for .eh_frame_hdr/DWARF index in the first place is conditional on defined(_LIBUNWIND_SUPPORT_DWARF_INDEX), although right now config.h will always define this macro. The support for DWARF unwind on bare metal has been validated within the ARTIQ environment[1]. [1]: https://m-labs.hk/artiq/ Modified: libunwind/trunk/src/AddressSpace.hpp Modified: libunwind/trunk/src/AddressSpace.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/AddressSpace.hpp?rev=321445&r1=321444&r2=321445&view=diff == --- libunwind/trunk/src/AddressSpace.hpp (original) +++ libunwind/trunk/src/AddressSpace.hpp Mon Dec 25 09:05:07 2017 @@ -83,6 +83,38 @@ namespace libunwind { } #endif +#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) + +// When statically linked on bare-metal, the symbols for the EH table are looked +// up without going through the dynamic loader. + +// The following linker script may be used to produce the necessary sections and symbols. +// Unless the --eh-frame-hdr linker option is provided, the section is not generated +// and does not take space in the output file. +// +// .eh_frame : +// { +// __eh_frame_start = .; +// KEEP(*(.eh_frame)) +// __eh_frame_end = .; +// } +// +// .eh_frame_hdr : +// { +// KEEP(*(.eh_frame_hdr)) +// } +// +// __eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0; +// __eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0; + +extern char __eh_frame_start; +extern char __eh_frame_end; + +#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) +extern char __eh_frame_hdr_start; +extern char __eh_frame_hdr_end; +#endif + #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) // When statically linked on bare-metal, the symbols for the EH table are looked @@ -348,6 +380,20 @@ inline bool LocalAddressSpace::findUnwin info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length; return true; } +#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) + // Bare metal is statically linked, so no need to ask the dynamic loader + info.dwarf_section_length = (uintptr_t)(&__eh_frame_end - &__eh_frame_start); + info.dwarf_section =(uintptr_t)(&__eh_frame_start); + _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x", + info.dwarf_section, info.dwarf_section_length); +#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) + info.dwarf_index_section =(uintptr_t)(&__eh_frame_hdr_start); + info.dwarf_index_section_length = (uintptr_t)(&__eh_frame_hdr_end - &__eh_frame_hdr_start); + _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: index section %X length %x", + info.dwarf_index_section, info.dwarf_index_section_length); +#endif + if (info.dwarf_section_length) +return true; #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) // Bare metal is statically linked, so no need to ask the dynamic loader info.arm_section =(uintptr_t)(&__exidx_start); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libunwind] r321440 - [libunwind] Avoid using C++ headers.
On 2017-12-25 19:04, Don Hinton wrote: Hi: This change breaks in a local debug build, e.g.,: /Users/dhinton/projects/llvm_project/libunwind/src/DwarfParser.hpp:559:28: error: no member named 'numeric_limits' in namespace 'std' assert(length < std::numeric_limits::max() && "pointer overflow"); ~^ Sorry, I missed this. Any idea on reformulating the assert in a way that does not require libcxx headers? Not having them significantly simplifies bare-metal builds... thanks... don On Mon, Dec 25, 2017 at 5:06 AM, whitequark via cfe-commits wrote: Author: whitequark Date: Mon Dec 25 05:06:09 2017 New Revision: 321440 URL: http://llvm.org/viewvc/llvm-project?rev=321440&view=rev [1] Log: [libunwind] Avoid using C++ headers. This is useful for building libunwind on libcxx-free systems. Modified: libunwind/trunk/src/DwarfParser.hpp Modified: libunwind/trunk/src/DwarfParser.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=321440&r1=321439&r2=321440&view=diff [2] == --- libunwind/trunk/src/DwarfParser.hpp (original) +++ libunwind/trunk/src/DwarfParser.hpp Mon Dec 25 05:06:09 2017 @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include "libunwind.h" #include "dwarf2.h" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits [3] Links: -- [1] http://llvm.org/viewvc/llvm-project?rev=321440&view=rev [2] http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=321440&r1=321439&r2=321440&view=diff [3] http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits -- whitequark ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] r321446 - [libunwind] Unbreak debug builds after r321440.
Author: whitequark Date: Mon Dec 25 12:04:47 2017 New Revision: 321446 URL: http://llvm.org/viewvc/llvm-project?rev=321446&view=rev Log: [libunwind] Unbreak debug builds after r321440. Modified: libunwind/trunk/src/DwarfParser.hpp Modified: libunwind/trunk/src/DwarfParser.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=321446&r1=321445&r2=321446&view=diff == --- libunwind/trunk/src/DwarfParser.hpp (original) +++ libunwind/trunk/src/DwarfParser.hpp Mon Dec 25 12:04:47 2017 @@ -17,7 +17,6 @@ #include #include #include -#include #include "libunwind.h" #include "dwarf2.h" @@ -26,6 +25,10 @@ namespace libunwind { +// Avoid relying on C++ headers. +template +static constexpr T pint_max_value() { return ~0; } + /// CFI_Parser does basic parsing of a CFI (Call Frame Information) records. /// See DWARF Spec for details: /// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html @@ -540,7 +543,7 @@ bool CFI_Parser::parseInstructions(A results->cfaRegister = 0; results->cfaExpression = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", @@ -556,7 +559,7 @@ bool CFI_Parser::parseInstructions(A results->savedRegisters[reg].location = kRegisterAtExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", " @@ -642,7 +645,7 @@ bool CFI_Parser::parseInstructions(A results->savedRegisters[reg].location = kRegisterIsExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libunwind] r321440 - [libunwind] Avoid using C++ headers.
On 2017-12-25 19:43, Don Hinton wrote: Here's the patch I applied locally. hth... don [snip] I've committed a slightly beautified version of the patch (below) as r321446. Cheers! From 8a4760bafc1123f09438587ee5432eabdec3d33d Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 25 Dec 2017 20:03:40 + Subject: [PATCH] [libunwind] Unbreak debug builds after r321440. --- src/DwarfParser.hpp | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/DwarfParser.hpp b/src/DwarfParser.hpp index 518101e..645ac21 100644 --- a/src/DwarfParser.hpp +++ b/src/DwarfParser.hpp @@ -17,7 +17,6 @@ #include #include #include -#include #include "libunwind.h" #include "dwarf2.h" @@ -26,6 +25,10 @@ namespace libunwind { +// Avoid relying on C++ headers. +template +static constexpr T pint_max_value() { return ~0; } + /// CFI_Parser does basic parsing of a CFI (Call Frame Information) records. /// See DWARF Spec for details: /// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html @@ -540,7 +543,7 @@ bool CFI_Parser::parseInstructions(A &addressSpace, pint_t instructions, results->cfaRegister = 0; results->cfaExpression = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", @@ -556,7 +559,7 @@ bool CFI_Parser::parseInstructions(A &addressSpace, pint_t instructions, results->savedRegisters[reg].location = kRegisterAtExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", " @@ -642,7 +645,7 @@ bool CFI_Parser::parseInstructions(A &addressSpace, pint_t instructions, results->savedRegisters[reg].location = kRegisterIsExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", -- 2.11.0 On Mon, Dec 25, 2017 at 11:26 AM, Don Hinton wrote: On Mon, Dec 25, 2017 at 11:09 AM, whitequark wrote: On 2017-12-25 19:04, Don Hinton wrote: Hi: This change breaks in a local debug build, e.g.,: /Users/dhinton/projects/llvm_project/libunwind/src/DwarfParser.hpp:559:28: error: no member named 'numeric_limits' in namespace 'std' assert(length < std::numeric_limits::max() && "pointer overflow"); ~^ Sorry, I missed this. Any idea on reformulating the assert in a way that does not require libcxx headers? Not having them significantly simplifies bare-metal builds... Well, assuming pint_t is some unsigned integer type, the max can be found like this: pint_t max_pint_t = ~0; So, that could be used in a pinch. thanks... don On Mon, Dec 25, 2017 at 5:06 AM, whitequark via cfe-commits wrote: Author: whitequark Date: Mon Dec 25 05:06:09 2017 New Revision: 321440 URL: http://llvm.org/viewvc/llvm-project?rev=321440&view=rev [1] [1] Log: [libunwind] Avoid using C++ headers. This is useful for building libunwind on libcxx-free systems. Modified: libunwind/trunk/src/DwarfParser.hpp Modified: libunwind/trunk/src/DwarfParser.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=321440&r1=321439&r2=321440&view=diff [2] [2] == --- libunwind/trunk/src/DwarfParser.hpp (original) +++ libunwind/trunk/src/DwarfParser.hpp Mon Dec 25 05:06:09 2017 @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include "libunwind.h" #include "dwarf2.h" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits [3] [3] Links: -- [1]
Re: [libunwind] r321440 - [libunwind] Avoid using C++ headers.
On 2017-12-25 20:32, Don Hinton wrote: While beauty is in the eye of the beholder, I'm not sure introducing a new template function in a header that's only used in that header is a good idea. Every file that includes DwarfParser.hpp is going to get that template function -- and someone may try to use it someday. That header is a header private to the libunwind implementation, and the template function is confined to `namespace libunwind`. However, if you did want to do that, you should handle signed types as well, which pint_max_value doesn't do. `pint_t` is an unsigned type in libunwind, the signed counterpart is `sint_t`. It should also assert for non-integral types. True, but I do not know enough C++ magic to implement that. AIUI std::numeric_limits implements this by specializing a template for every integral type, which is not something I will do here. Of course there's a standard template for checking whether a type is integral, but that also lives in libcxx. On Mon, Dec 25, 2017 at 12:06 PM, whitequark wrote: On 2017-12-25 19:43, Don Hinton wrote: Here's the patch I applied locally. hth... don [snip] I've committed a slightly beautified version of the patch (below) as r321446. Cheers! From 8a4760bafc1123f09438587ee5432eabdec3d33d Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 25 Dec 2017 20:03:40 + Subject: [PATCH] [libunwind] Unbreak debug builds after r321440. --- src/DwarfParser.hpp | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/DwarfParser.hpp b/src/DwarfParser.hpp index 518101e..645ac21 100644 --- a/src/DwarfParser.hpp +++ b/src/DwarfParser.hpp @@ -17,7 +17,6 @@ #include #include #include -#include #include "libunwind.h" #include "dwarf2.h" @@ -26,6 +25,10 @@ namespace libunwind { +// Avoid relying on C++ headers. +template +static constexpr T pint_max_value() { return ~0; } + /// CFI_Parser does basic parsing of a CFI (Call Frame Information) records. /// See DWARF Spec for details: /// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html [1] @@ -540,7 +543,7 @@ bool CFI_Parser::parseInstructions(A &addressSpace, pint_t instructions, results->cfaRegister = 0; results->cfaExpression = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", @@ -556,7 +559,7 @@ bool CFI_Parser::parseInstructions(A &addressSpace, pint_t instructions, results->savedRegisters[reg].location = kRegisterAtExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", " @@ -642,7 +645,7 @@ bool CFI_Parser::parseInstructions(A &addressSpace, pint_t instructions, results->savedRegisters[reg].location = kRegisterIsExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", -- 2.11.0 On Mon, Dec 25, 2017 at 11:26 AM, Don Hinton wrote: On Mon, Dec 25, 2017 at 11:09 AM, whitequark wrote: On 2017-12-25 19:04, Don Hinton wrote: Hi: This change breaks in a local debug build, e.g.,: /Users/dhinton/projects/llvm_project/libunwind/src/DwarfParser.hpp:559:28: error: no member named 'numeric_limits' in namespace 'std' assert(length < std::numeric_limits::max() && "pointer overflow"); ~^ Sorry, I missed this. Any idea on reformulating the assert in a way that does not require libcxx headers? Not having them significantly simplifies bare-metal builds... Well, assuming pint_t is some unsigned integer type, the max can be found like this: pint_t max_pint_t = ~0; So, that could be used in a pinch. thanks... don On Mon, Dec 25, 2017 at 5:06 AM, whitequark via cfe-commits wrote: Author: whitequark Date: Mon Dec 25 05:06:09 2017 New Revision: 321440 URL: http://llvm.org/viewvc/llvm-proj
[libunwind] r321448 - [libunwind] Remove dubious template function. NFC.
Author: whitequark Date: Mon Dec 25 13:08:41 2017 New Revision: 321448 URL: http://llvm.org/viewvc/llvm-project?rev=321448&view=rev Log: [libunwind] Remove dubious template function. NFC. Per review by Don Hinton. Modified: libunwind/trunk/src/DwarfParser.hpp Modified: libunwind/trunk/src/DwarfParser.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=321448&r1=321447&r2=321448&view=diff == --- libunwind/trunk/src/DwarfParser.hpp (original) +++ libunwind/trunk/src/DwarfParser.hpp Mon Dec 25 13:08:41 2017 @@ -25,10 +25,6 @@ namespace libunwind { -// Avoid relying on C++ headers. -template -static constexpr T pint_max_value() { return ~0; } - /// CFI_Parser does basic parsing of a CFI (Call Frame Information) records. /// See DWARF Spec for details: /// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html @@ -543,7 +539,7 @@ bool CFI_Parser::parseInstructions(A results->cfaRegister = 0; results->cfaExpression = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < pint_max_value() && "pointer overflow"); + assert(length < static_cast(~0) && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", @@ -559,7 +555,7 @@ bool CFI_Parser::parseInstructions(A results->savedRegisters[reg].location = kRegisterAtExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < pint_max_value() && "pointer overflow"); + assert(length < static_cast(~0) && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", " @@ -645,7 +641,7 @@ bool CFI_Parser::parseInstructions(A results->savedRegisters[reg].location = kRegisterIsExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < pint_max_value() && "pointer overflow"); + assert(length < static_cast(~0) && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libunwind] r321440 - [libunwind] Avoid using C++ headers.
On 2017-12-25 20:54, Don Hinton wrote: On Mon, Dec 25, 2017 at 12:43 PM, whitequark wrote: On 2017-12-25 20:32, Don Hinton wrote: It should also assert for non-integral types. True, but I do not know enough C++ magic to implement that. AIUI std::numeric_limits implements this by specializing a template for every integral type, which is not something I will do here. Of course there's a standard template for checking whether a type is integral, but that also lives in libcxx. Why not just use static_cast(~0) and avoid all these issues? r321448. Thanks for the review! You might have a point that this doesn't apply in your case, but it's a good habit to get into. On Mon, Dec 25, 2017 at 12:06 PM, whitequark wrote: On 2017-12-25 19:43, Don Hinton wrote: Here's the patch I applied locally. hth... don [snip] I've committed a slightly beautified version of the patch (below) as r321446. Cheers! From 8a4760bafc1123f09438587ee5432eabdec3d33d Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 25 Dec 2017 20:03:40 + Subject: [PATCH] [libunwind] Unbreak debug builds after r321440. --- src/DwarfParser.hpp | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/DwarfParser.hpp b/src/DwarfParser.hpp index 518101e..645ac21 100644 --- a/src/DwarfParser.hpp +++ b/src/DwarfParser.hpp @@ -17,7 +17,6 @@ #include #include #include -#include #include "libunwind.h" #include "dwarf2.h" @@ -26,6 +25,10 @@ namespace libunwind { +// Avoid relying on C++ headers. +template +static constexpr T pint_max_value() { return ~0; } + /// CFI_Parser does basic parsing of a CFI (Call Frame Information) records. /// See DWARF Spec for details: /// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html [5] [1] @@ -540,7 +543,7 @@ bool CFI_Parser::parseInstructions(A &addressSpace, pint_t instructions, results->cfaRegister = 0; results->cfaExpression = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", @@ -556,7 +559,7 @@ bool CFI_Parser::parseInstructions(A &addressSpace, pint_t instructions, results->savedRegisters[reg].location = kRegisterAtExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", " @@ -642,7 +645,7 @@ bool CFI_Parser::parseInstructions(A &addressSpace, pint_t instructions, results->savedRegisters[reg].location = kRegisterIsExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits::max() && "pointer overflow"); + assert(length < pint_max_value() && "pointer overflow"); p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", -- 2.11.0 On Mon, Dec 25, 2017 at 11:26 AM, Don Hinton wrote: On Mon, Dec 25, 2017 at 11:09 AM, whitequark wrote: On 2017-12-25 19:04, Don Hinton wrote: Hi: This change breaks in a local debug build, e.g.,: /Users/dhinton/projects/llvm_project/libunwind/src/DwarfParser.hpp:559:28: error: no member named 'numeric_limits' in namespace 'std' assert(length < std::numeric_limits::max() && "pointer overflow"); ~^ Sorry, I missed this. Any idea on reformulating the assert in a way that does not require libcxx headers? Not having them significantly simplifies bare-metal builds... Well, assuming pint_t is some unsigned integer type, the max can be found like this: pint_t max_pint_t = ~0; So, that could be used in a pinch. thanks... don On Mon, Dec 25, 2017 at 5:06 AM, whitequark via cfe-commits wrote: Author: whitequark Date: Mon Dec 25 05:06:09 2017 New Revision: 321440 URL: http://llvm.org/viewvc/llvm-project?rev=321440&view=rev [1] [2] [1] [1] Log: [libunwind] Avoid using C++ headers. This is useful for building libunwind on libcxx-free systems. Modified: libunwind/trunk/src/DwarfParser.hpp Modified: libunwind/trunk/src/DwarfParser.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=3
[PATCH] D17952: [Clang] Accept absolute paths in the -fuse-ld option
whitequark created this revision. whitequark added a reviewer: majnemer. whitequark added a subscriber: cfe-commits. whitequark set the repository for this revision to rL LLVM. Herald added a subscriber: aemerson. This patch extends the -fuse-ld option to accept a full path to an executable and use it verbatim to invoke the linker. There are generally two reasons to desire this. The first reason relates to the sad truth is that Clang is retargetable, Binutils are not. While any Clang from a binary distribution is sufficient to compile code for a wide range of architectures and prefixed BFD linkers (e.g. installed as /usr/bin/arm-none-linux-gnueabi-ld) as well as cross-compiled libc's (for non-bare-metal targets) are widely available, including on all Debian derivatives, it is impossible to use them together because the -fuse-ld= option allows to specify neither a linker prefix nor a full path to one. The second reason is linker development, both when porting existing linkers to new architectures and when working on a new linker such as LLD. Repository: rL LLVM http://reviews.llvm.org/D17952 Files: cfe/trunk/lib/Driver/ToolChain.cpp Index: cfe/trunk/lib/Driver/ToolChain.cpp === --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { -StringRef Suffix = A->getValue(); - -// If we're passed -fuse-ld= with no argument, or with the argument ld, -// then use whatever the default system linker is. -if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - -llvm::SmallString<8> LinkerName("ld."); -LinkerName.append(Suffix); - -std::string LinkerPath(GetProgramPath(LinkerName.c_str())); -if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; +StringRef UseLinker = A->getValue(); + +if (UseLinker[0] == '/') { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) +return UseLinker; +} else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") +return GetProgramPath("ld"); + + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) +return LinkerPath; +} getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return ""; Index: cfe/trunk/lib/Driver/ToolChain.cpp === --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { -StringRef Suffix = A->getValue(); - -// If we're passed -fuse-ld= with no argument, or with the argument ld, -// then use whatever the default system linker is. -if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - -llvm::SmallString<8> LinkerName("ld."); -LinkerName.append(Suffix); - -std::string LinkerPath(GetProgramPath(LinkerName.c_str())); -if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; +StringRef UseLinker = A->getValue(); + +if (UseLinker[0] == '/') { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) +return UseLinker; +} else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") +return GetProgramPath("ld"); + + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) +return LinkerPath; +} getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return ""; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17952: [Clang] Accept absolute paths in the -fuse-ld option
whitequark marked an inline comment as done. Comment at: cfe/trunk/lib/Driver/ToolChain.cpp:352 @@ +351,3 @@ +return UseLinker; +} else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, silvas wrote: > No need for else after return. This would change behavior when an absolute path is passed but doesn't exist; clang will try to append it to "ld." and display some silly error message. Repository: rL LLVM http://reviews.llvm.org/D17952 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17952: [Clang] Accept absolute paths in the -fuse-ld option
whitequark updated this revision to Diff 50021. whitequark added a comment. Windows compatibility Repository: rL LLVM http://reviews.llvm.org/D17952 Files: cfe/trunk/lib/Driver/ToolChain.cpp Index: cfe/trunk/lib/Driver/ToolChain.cpp === --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { -StringRef Suffix = A->getValue(); - -// If we're passed -fuse-ld= with no argument, or with the argument ld, -// then use whatever the default system linker is. -if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - -llvm::SmallString<8> LinkerName("ld."); -LinkerName.append(Suffix); - -std::string LinkerPath(GetProgramPath(LinkerName.c_str())); -if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; +StringRef UseLinker = A->getValue(); + +if (llvm::sys::path::is_absolute(UseLinker)) { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) +return UseLinker; +} else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") +return GetProgramPath("ld"); + + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) +return LinkerPath; +} getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return ""; Index: cfe/trunk/lib/Driver/ToolChain.cpp === --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { -StringRef Suffix = A->getValue(); - -// If we're passed -fuse-ld= with no argument, or with the argument ld, -// then use whatever the default system linker is. -if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - -llvm::SmallString<8> LinkerName("ld."); -LinkerName.append(Suffix); - -std::string LinkerPath(GetProgramPath(LinkerName.c_str())); -if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; +StringRef UseLinker = A->getValue(); + +if (llvm::sys::path::is_absolute(UseLinker)) { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) +return UseLinker; +} else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") +return GetProgramPath("ld"); + + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) +return LinkerPath; +} getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return ""; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17952: [Clang] Accept absolute paths in the -fuse-ld option
whitequark updated this revision to Diff 50097. whitequark added a comment. Added a test Repository: rL LLVM http://reviews.llvm.org/D17952 Files: cfe/trunk/lib/Driver/ToolChain.cpp cfe/trunk/test/Driver/fuse-ld.c Index: cfe/trunk/test/Driver/fuse-ld.c === --- cfe/trunk/test/Driver/fuse-ld.c +++ cfe/trunk/test/Driver/fuse-ld.c @@ -1,4 +1,10 @@ // RUN: %clang %s -### \ +// RUN: -fuse-ld=/usr/local/bin/or1k-linux-ld 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ABSOLUTE-LD +// CHECK-ABSOLUTE-LD: /usr/local/bin/or1k-linux-ld + + +// RUN: %clang %s -### \ // RUN: -target x86_64-unknown-freebsd 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-FREEBSD-LD // CHECK-FREEBSD-LD: ld Index: cfe/trunk/lib/Driver/ToolChain.cpp === --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { -StringRef Suffix = A->getValue(); - -// If we're passed -fuse-ld= with no argument, or with the argument ld, -// then use whatever the default system linker is. -if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - -llvm::SmallString<8> LinkerName("ld."); -LinkerName.append(Suffix); - -std::string LinkerPath(GetProgramPath(LinkerName.c_str())); -if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; +StringRef UseLinker = A->getValue(); + +if (llvm::sys::path::is_absolute(UseLinker)) { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) +return UseLinker; +} else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") +return GetProgramPath("ld"); + + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) +return LinkerPath; +} getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return ""; Index: cfe/trunk/test/Driver/fuse-ld.c === --- cfe/trunk/test/Driver/fuse-ld.c +++ cfe/trunk/test/Driver/fuse-ld.c @@ -1,4 +1,10 @@ // RUN: %clang %s -### \ +// RUN: -fuse-ld=/usr/local/bin/or1k-linux-ld 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ABSOLUTE-LD +// CHECK-ABSOLUTE-LD: /usr/local/bin/or1k-linux-ld + + +// RUN: %clang %s -### \ // RUN: -target x86_64-unknown-freebsd 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-FREEBSD-LD // CHECK-FREEBSD-LD: ld Index: cfe/trunk/lib/Driver/ToolChain.cpp === --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { -StringRef Suffix = A->getValue(); - -// If we're passed -fuse-ld= with no argument, or with the argument ld, -// then use whatever the default system linker is. -if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - -llvm::SmallString<8> LinkerName("ld."); -LinkerName.append(Suffix); - -std::string LinkerPath(GetProgramPath(LinkerName.c_str())); -if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; +StringRef UseLinker = A->getValue(); + +if (llvm::sys::path::is_absolute(UseLinker)) { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) +return UseLinker; +} else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") +return GetProgramPath("ld"); + + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) +return LinkerPath; +} getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return ""; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17952: [Clang] Accept absolute paths in the -fuse-ld option
This revision was automatically updated to reflect the committed changes. Closed by commit rL262996: Accept absolute paths in the -fuse-ld option. (authored by whitequark). Repository: rL LLVM http://reviews.llvm.org/D17952 Files: cfe/trunk/lib/Driver/ToolChain.cpp cfe/trunk/test/Driver/fuse-ld.c Index: cfe/trunk/test/Driver/fuse-ld.c === --- cfe/trunk/test/Driver/fuse-ld.c +++ cfe/trunk/test/Driver/fuse-ld.c @@ -1,4 +1,10 @@ // RUN: %clang %s -### \ +// RUN: -fuse-ld=/usr/local/bin/or1k-linux-ld 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ABSOLUTE-LD +// CHECK-ABSOLUTE-LD: /usr/local/bin/or1k-linux-ld + + +// RUN: %clang %s -### \ // RUN: -target x86_64-unknown-freebsd 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-FREEBSD-LD // CHECK-FREEBSD-LD: ld Index: cfe/trunk/lib/Driver/ToolChain.cpp === --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { -StringRef Suffix = A->getValue(); +StringRef UseLinker = A->getValue(); -// If we're passed -fuse-ld= with no argument, or with the argument ld, -// then use whatever the default system linker is. -if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - -llvm::SmallString<8> LinkerName("ld."); -LinkerName.append(Suffix); - -std::string LinkerPath(GetProgramPath(LinkerName.c_str())); -if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; +if (llvm::sys::path::is_absolute(UseLinker)) { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) +return UseLinker; +} else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") +return GetProgramPath("ld"); + + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) +return LinkerPath; +} getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return ""; Index: cfe/trunk/test/Driver/fuse-ld.c === --- cfe/trunk/test/Driver/fuse-ld.c +++ cfe/trunk/test/Driver/fuse-ld.c @@ -1,4 +1,10 @@ // RUN: %clang %s -### \ +// RUN: -fuse-ld=/usr/local/bin/or1k-linux-ld 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ABSOLUTE-LD +// CHECK-ABSOLUTE-LD: /usr/local/bin/or1k-linux-ld + + +// RUN: %clang %s -### \ // RUN: -target x86_64-unknown-freebsd 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-FREEBSD-LD // CHECK-FREEBSD-LD: ld Index: cfe/trunk/lib/Driver/ToolChain.cpp === --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -342,19 +342,26 @@ std::string ToolChain::GetLinkerPath() const { if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { -StringRef Suffix = A->getValue(); +StringRef UseLinker = A->getValue(); -// If we're passed -fuse-ld= with no argument, or with the argument ld, -// then use whatever the default system linker is. -if (Suffix.empty() || Suffix == "ld") - return GetProgramPath("ld"); - -llvm::SmallString<8> LinkerName("ld."); -LinkerName.append(Suffix); - -std::string LinkerPath(GetProgramPath(LinkerName.c_str())); -if (llvm::sys::fs::exists(LinkerPath)) - return LinkerPath; +if (llvm::sys::path::is_absolute(UseLinker)) { + // If we're passed -fuse-ld= with what looks like an absolute path, + // don't attempt to second-guess that. + if (llvm::sys::fs::exists(UseLinker)) +return UseLinker; +} else { + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (UseLinker.empty() || UseLinker == "ld") +return GetProgramPath("ld"); + + llvm::SmallString<8> LinkerName("ld."); + LinkerName.append(UseLinker); + + std::string LinkerPath(GetProgramPath(LinkerName.c_str())); + if (llvm::sys::fs::exists(LinkerPath)) +return LinkerPath; +} getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return ""; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits