|
31 | 31 |
|
32 | 32 | #include "llvm/ADT/PointerUnion.h"
|
33 | 33 | #include "llvm/ADT/StringRef.h"
|
| 34 | +#include "llvm/Support/ARMBuildAttributes.h" |
34 | 35 | #include "llvm/Support/MathExtras.h"
|
35 | 36 |
|
36 | 37 | #define CASE_AND_STREAM(s, def, width) \
|
@@ -1516,6 +1517,93 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l
|
1516 | 1517 | return error;
|
1517 | 1518 | }
|
1518 | 1519 |
|
| 1520 | +void |
| 1521 | +ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, ArchSpec &arch_spec) |
| 1522 | +{ |
| 1523 | + lldb::offset_t Offset = 0; |
| 1524 | + |
| 1525 | + uint8_t FormatVersion = data.GetU8(&Offset); |
| 1526 | + if (FormatVersion != llvm::ARMBuildAttrs::Format_Version) |
| 1527 | + return; |
| 1528 | + |
| 1529 | + Offset = Offset + sizeof(uint32_t); // Section Length |
| 1530 | + llvm::StringRef VendorName = data.GetCStr(&Offset); |
| 1531 | + |
| 1532 | + if (VendorName != "aeabi") |
| 1533 | + return; |
| 1534 | + |
| 1535 | + if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment) |
| 1536 | + arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); |
| 1537 | + |
| 1538 | + while (Offset < length) |
| 1539 | + { |
| 1540 | + uint8_t Tag = data.GetU8(&Offset); |
| 1541 | + uint32_t Size = data.GetU32(&Offset); |
| 1542 | + |
| 1543 | + if (Tag != llvm::ARMBuildAttrs::File || Size == 0) |
| 1544 | + continue; |
| 1545 | + |
| 1546 | + while (Offset < length) |
| 1547 | + { |
| 1548 | + uint64_t Tag = data.GetULEB128(&Offset); |
| 1549 | + switch (Tag) |
| 1550 | + { |
| 1551 | + default: |
| 1552 | + if (Tag < 32) |
| 1553 | + data.GetULEB128(&Offset); |
| 1554 | + else if (Tag % 2 == 0) |
| 1555 | + data.GetULEB128(&Offset); |
| 1556 | + else |
| 1557 | + data.GetCStr(&Offset); |
| 1558 | + |
| 1559 | + break; |
| 1560 | + |
| 1561 | + case llvm::ARMBuildAttrs::CPU_raw_name: |
| 1562 | + case llvm::ARMBuildAttrs::CPU_name: |
| 1563 | + data.GetCStr(&Offset); |
| 1564 | + |
| 1565 | + break; |
| 1566 | + |
| 1567 | + case llvm::ARMBuildAttrs::THUMB_ISA_use: |
| 1568 | + { |
| 1569 | + uint64_t ThumbISA = data.GetULEB128(&Offset); |
| 1570 | + |
| 1571 | + // NOTE: ignore ThumbISA == llvm::ARMBuildAttrs::AllowThumbDerived |
| 1572 | + // since that derives it based on the architecutre/profile |
| 1573 | + if (ThumbISA == llvm::ARMBuildAttrs::AllowThumb32) |
| 1574 | + if (arch_spec.GetTriple().getArch() == llvm::Triple::UnknownArch || |
| 1575 | + arch_spec.GetTriple().getArch() == llvm::Triple::arm) |
| 1576 | + arch_spec.GetTriple().setArch(llvm::Triple::thumb); |
| 1577 | + |
| 1578 | + break; |
| 1579 | + } |
| 1580 | + case llvm::ARMBuildAttrs::ABI_VFP_args: |
| 1581 | + { |
| 1582 | + uint64_t VFPArgs = data.GetULEB128(&Offset); |
| 1583 | + |
| 1584 | + if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) |
| 1585 | + { |
| 1586 | + if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment || |
| 1587 | + arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF) |
| 1588 | + arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); |
| 1589 | + |
| 1590 | + arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float); |
| 1591 | + } |
| 1592 | + else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) |
| 1593 | + { |
| 1594 | + if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment || |
| 1595 | + arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI) |
| 1596 | + arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF); |
| 1597 | + |
| 1598 | + arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); |
| 1599 | + } |
| 1600 | + |
| 1601 | + break; |
| 1602 | + } |
| 1603 | + } |
| 1604 | + } |
| 1605 | + } |
| 1606 | +} |
1519 | 1607 |
|
1520 | 1608 | //----------------------------------------------------------------------
|
1521 | 1609 | // GetSectionHeaderInfo
|
@@ -1648,6 +1736,18 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
1648 | 1736 | arch_spec.SetFlags (arch_flags);
|
1649 | 1737 | }
|
1650 | 1738 |
|
| 1739 | + if (arch_spec.GetMachine() == llvm::Triple::arm || arch_spec.GetMachine() == llvm::Triple::thumb) |
| 1740 | + { |
| 1741 | + DataExtractor data; |
| 1742 | + |
| 1743 | + if (sheader.sh_type != SHT_ARM_ATTRIBUTES) |
| 1744 | + continue; |
| 1745 | + if (section_size == 0 || set_data(data, sheader.sh_offset, section_size) != section_size) |
| 1746 | + continue; |
| 1747 | + |
| 1748 | + ParseARMAttributes(data, section_size, arch_spec); |
| 1749 | + } |
| 1750 | + |
1651 | 1751 | if (name == g_sect_name_gnu_debuglink)
|
1652 | 1752 | {
|
1653 | 1753 | DataExtractor data;
|
|
0 commit comments