text:
Building Family Equality in Every Classroom
Parents can engage with their children's schools in a variety of ways to help ensure a safe, supportive learning environment for their children. This list below offers some specific suggestions. Do those which feel most comfortable to you.
Ask the principal and your child's teacher if they are aware of other LGBT families at the school currently or in the past. Ask how school staff deal with comments like "that's so gay" or other anti-LGBT slurs. Ask whether the staff has received training on how to support students with LGBT families. Ask the school librarian if the library contains books that include LGBT families. Find out who is on the school board, PTA and other influential groups at school and research their records regardng inclusiveness.
Be Out
Be as out as your feel your safely can be in your community. Meet with your principal and teacher to introduce your family. Introduce yourselves to other families at school. Let your child's teacher know what language you use to describe your family relationships (e.g. Daddy/Papa, Eva has two moms). Be a guest speaker in your child's class, at a staff meeting or PTA meeting.
Parents can have a huge influence in their school communities when they get involved. Volunteer in your child's classroom or help out in the school. Take a leadership role- join the PTA, site council, diversity committee, or curriculum review committee. Make your voice heard-express your thanks when the school or district takes steps to be LGBT inclusive and vocally oppose any anti-LGBT policies or actions. Speak up at a school board meeting or email board members and district administrators about issues that impact your family.
Check Policies
Take a look at your school or district's policies addressing discrimination, harassment and bullying to see if they include sexual orientation and gender identity/expression. If they don't, work with administrators, teachers and other parents to change them.
Fix Forms
If your school forms say "mother/father" rather than "parent/guardian," ask if they could be updated to include all families
Provide Resources
Suggest specific, concrete ways the school could change to be more supportive of your family. Offer suggestions for age-appropriate books, videos, curriculum and other materials that include LGBT families. Donate some of these resources if you can. Offer suggestions for how to deal with potentially sticky situations like Father's Day, Mother's Day, family-tree assignments, or how to respond when other parents have questions about your family. Let your principal and teacher know about LGBT-related staff development opportunities, such as local trainers or conferences.
Organize a get-together with the parents/guardians of other children in your child's classroom. If there are other LGBT families at your school, organize an LGBT and Ally potluck at school. Start an LGBT school advocacy group in your district or region. There is great strength in numbers and in diverse voices advocating for fairness.
Whether your school is just beginning the process of becoming a welcoming environment for LGBT families or has already taken great strides to do so, continue to raise your expectations. Nearly every school could take further steps to become even more welcoming and inclusive of LGBT families. Help your school move to the next level.
Download the Back to School Tool


text:
Cancer Immun. 2009 Nov 2;9:10.
In vivo major histocompatibility complex class I (MHCI) expression on MHCIlow tumor cells is regulated by gammadelta T and NK cells during the early steps of tumor growth.
Riond J1, Rodriguez S, Nicolau ML, al Saati T, Gairin JE.
Institut des Sciences et Technologies du Médicament de Toulouse, UMR2587, CNRS-Pierre Fabre, Toulouse, France. joelle.riond@istmt.cnrs.fr
Cell surface expression of MHC class I molecules by tumor cells is determinant in the interplay between tumor cells and the immune system. Nevertheless, the mechanisms which regulate MHCI expression on tumor cells are not clear. We previously showed that immune innate cells from the spleen can regulate MHCI expression on MHCI(low) tumor cells. Here, using the murine model of B16 melanoma, we demonstrate that the MHCI status of tumor cells in vivo is regulated by the microenvironment. In subcutaneous grafts, induction of MHCI molecules on tumor cells is concomitant to the recruitment of lymphocytes and relies on an IFNgamma-mediated mechanism. gammadelta T and NK cells are essential to this regulation. A small proportion of tumor-infiltrating NK cells and gammadelta T cells were found to produce IFNgamma, suggesting a possible direct participation to the MHCI increase on the tumor cells upon tumor cell recognition. Depletion of gammadelta T cells increases the tumor growth rate, confirming their anti-tumoral role in our model. Taken together, our results demonstrate that in vivo, NK and gammadelta T cells play a dual role during the early growth of MHCI(low) tumor cells. In addition to controlling the growth of tumor cells, they contribute to modifying the immunogenic profile of residual tumor cells.
Figure 1; Upregulation of MHCI expression on B16F10-GFP tumors in vivo.
B16F10-GFP cells were injected subcutaneously (sc), via the tail vein (iv) or intradermally (id). Ten days later, tumor masses (sc, id), lungs (iv) and the lymph node draining the id tumor (ln) were recovered and dissociated. B16F10-GFP cells grown in vitro (vitro) and cells extracted from the mice spleens (splenocytes) were used as controls. Cell suspensions were labeled with anti-H2-Db antibody (black) or a control isotype (grey), followed by an APC-labeled secondary antibody. Fluorescence intensity was measured by flow cytometry on DAPI negative B16F10-GFP cells.
In vivo major histocompatibility complex class I (MHCI) expression on MHCIlow tumor cells is regulated by γδ T and NK cells during the early steps of tumor growth
Cancer Immun. 2009;9:10.
Figure 2; MHCI upregulation occurs rapidly after the tumor cell graft.
B16F10-GFP cells were injected subcutaneously in Matrigel at day 0. Mice were sacrificed at the times indicated and Matrigel plugs were resected and dissociated. As a control, B16F10-GFP cells were plated in vitro at day 0, with or without Matrigel. B16F10-GFP cells were analyzed for H2-Db expression as described in . (A) Kinetics of H2-Db expression on B16F10-GFP cells extracted from Matrigel plugs (in vivo) or grown in vitro, with or without Matrigel. Data are expressed as the mean ± SD of triplicate assays (**: P < 0.05). (B) Immunochemistry analysis of frozen sections from in vivo Matrigel plugs containing B16F10-GFP cells at day 3, immunostained with an anti-H2-Kb antibody.
Figure 3; MHCI upregulation is concomitant to host cell recruitment to the tumor site.
Mice were injected either with PBS (A) or 5 x 105 B16F10-GFP cells (B-C) in Matrigel. At the times indicated, Matrigel plugs were resected, fixed and embedded in paraffin. Sections were labeled with hematoxylin and eosin (A-C). (C) Magnification (5x) of panel B. Black and white arrows indicate respectively tumor cells and infiltrating cells. (D) Tumor cells and infiltrating cells were counted in ten surface sections (260 µm x 26 µm) designed parallel to the edge, from the edge towards the center of the Matrigel plugs. Histograms show the number of B16F10-GFP cells (black bars) and infiltrating cells (white bars) in surface sections from one representative slice of six from two different Matrigel plugs containing tumor cells resected respectively at 1 h, 5 h, day 1, day 2 and day 3. The number of infiltrating cells in equivalent surface sections from one representative slice from two Matrigel plugs containing PBS only is shown as grey bars. Values are indicated above the bars when they are out of scale.
Figure 4; The early stage of tumor-specific recruitment concerns mostly lymphocytes.
Mice were injected with 5 x 105 B16F10-GFP cells in Matrigel. At the times indicated, Matrigel plugs were resected, fixed, and embedded in paraffin. Matrigel sections were labeled with anti-CD3 or -F4/80 antibodies. Dotted lines indicate the edge of the Matrigel (M). Black and white arrows indicate tumor cells and CD3 or F4/80 positive cells respectively.
Figure 5; Flow cytometry analysis of lymphocytes involved in the early stages of tumor-specific recruitment.
(A) Mice were injected either with PBS or 5 x 105 B16F10-GFP cells in Matrigel. At the times indicated, Matrigel plugs were resected and dissociated. Cellular suspensions were labeled with anti-CD3, -CD4, -CD8, -NK, -TCRγδ antibodies, and analyzed by flow cytometry. For each condition, 5 to 6 independent Matrigel plugs were analyzed. The total number of cells (circles) recovered from each individual plug and the medians of mice groups (bars) are reported. For each time point, the significance of the difference between B16 groups and PBS groups was determined by the Mann-Whitney rank sum test. Abbreviations: ns, non significant; **, P < 0.05; ***, P < 0.005. (B) Medians of the values in panel A are reported as histograms.
Figure 6; Endogenous IFNγ modulates MHCI molecules on tumor cells.
(A) B16F10-GFP cells were co-cultured 2 days with extract of one day-plugs collected from mice injected either with PBS or non-fluorescent B16F10 cells (ex vivo), or with Matrigel containing IFNγ or not (in vitro). H2-Db expression was measured on B16F10-GFP cells. (B) B16F10-GFP cells were injected with Matrigel in C57Bl/6 or C57Bl/6 IFNγ0/0 mice (black or white circles, respectively; n = 5 or 6). At the times indicated, cells contained in the Matrigel were extracted and B16F10-GFP cells were analyzed for the expression of H2-Db. Data are expressed as the mean ± SD of triplicate assays (Mann-Whitney rank sum test; **: P < 0.02).
Figure 7; In vivo modulation of MHCI molecules expression is altered in TCRγ0/0 and NK-depleted mice.
(A) B16F10-GFP cells or PBS were injected with Matrigel in C57Bl/6 mice. At day 1, cells contained in Matrigel plugs from five mice were extracted, pooled and labeled for intracellular IFNγ. The percentage of IFNγ positive cells in the indicated subsets are expressed as a histogram. Gating of IFNγ positive cells was defined using an isotypic control antibody. The significance of the differences in the percentage of positive cells was analyzed using a z-test (**: P < 0.05; ***: P < 0.005). (B) B16F10-GFP cells were injected with Matrigel in C57Bl/6 (black circles), TCRγ-depleted C57Bl/6 (white circles) and NK-depleted C57Bl/6 (grey circles) mice (n = 4). At the times indicated, cells contained in Matrigel were extracted and B16F10-GFP cells were analyzed for H2-Db expression. (C) B16F10-GFP cells were injected without Matrigel in C57Bl/6 (black circles) and TCRγ0/0 (white circles) mice (n = 4). Tumor growth is reported for the times indicated (**: P < 0.05).
Cell Proliferation
Cell Transformation, Neoplastic/immunology
Cell Transformation, Neoplastic/metabolism
Cell Transformation, Neoplastic/pathology
Histocompatibility Antigens Class I/immunology*
Histocompatibility Antigens Class I/metabolism
Interferon-gamma/immunology
Killer Cells, Natural/immunology*
Melanoma/immunology*
Melanoma/metabolism
Melanoma/pathology*
Neoplasm Transplantation
Receptors, Antigen, T-Cell, gamma-delta/immunology
T-Lymphocytes/immunology*
Up-Regulation
Histocompatibility Antigens Class I
Receptors, Antigen, T-Cell, gamma-delta
Interferon-gamma
Academy of Cancer Immunology
Melanoma - MedlinePlus Health Information

redpajama_set_name: RedPajamaCommonCrawl


After last night's Idol Gives Back finale/telethon, there were two lingering questions: How much money, exactly, did the show raise from viewers and its sponsors, and where were the celebrities who were supposed to show up but were absent?
As to the donations from various corporations and sponsors, Reuters asked and none would give details. "Sponsors Coca-Cola and Ford declined on Thursday to say how much they had donated, citing business confidentiality. Ford said its contribution was tied to Internet downloads of its 'Idol' music videos. AT&T could not be reached for comment," Reuters reports.
As to the missing celebrities, some cancelled and others were cut. When Ryan Seacrest announced the event earlier this season, he promised appearances by Borat, Gwen Stefani, Pink, and others who didn't show. Gwen Stefani and Pink's appearances "were 'cut for time,' and their segments should air on upcoming episodes," TMZ reported.


text:
in Education, Literacy, Math, Nashville, Reading, Science, Volunteerism
Nebraska Huskers Provide Hope for Middle Tennessee Students
Emily with her mom, Julie
Written by: Cole Gray
Doing Good's Nashville Volunteer of the Month Emily Fay is passionate about the University of Nebraska and serving others. In 2007, two years after moving to Nashville, she decided to combine her passions by founding Nashville Huskers, a nonprofit alumni association that has used member dues and merchandise sales to raise $18,000 in scholarship for Tennessee high school students looking to attend the University of Nebraska.
"I just wanted to watch football with other Nebraskans. That's what it was when I started," said Fay. She missed being surrounded by other Cornhuskers after growing up in a University of Nebraska household in Loveland, Colo., then attending Nebraska, and finally ending up in a sea of SEC fans in Nashville. So, back in 2007, Fay sent out some Facebook message cold-calls and 80 fans showed up to watch a football game.
Fast-forward eight seasons, and Nashville Huskers has hosted over 100 watch parties and over 10,000 guests. Though it started on Facebook, it's now an official Nebraska Alumni chapter, and the community Fay started is supporting Middle Tennessee's students.
"We want to send more people to the Big Ten, and we want to send more people to Nebraska because it's one of the flyover states. People forget about it. It's a beautiful campus with so much opportunity there. They're doing amazing research, they're doing wonderful things on campus, and to be able to send someone here in that direction just excites me. There's so much opportunity."


text:
Your question: How much did Richard Jewell get settlements?
Did Richard Jewell get any settlement?
How much money did Richard Jewell make?
Did Tom Shaw ever apologize to Richard Jewell?
What happened to AJC reporter Kathy Scruggs?
How did Eric Rudolph get caught?
Did Kathy Scruggs sleep with FBI agent?
Is Richard Jewell alive?
Did Richard Jewell place the bomb?
Is Netflix Richard Jewell true?
Did the FBI really trick Richard Jewell?
Why was Richard Jewell controversial?
How accurate is Richard Jewell?
Was Kathy Scruggs a drug addict?
Did Kathy Scruggs do drugs?
In December 1996, NBC negotiated a settlement with Jewell for a reported $500,000.
He sued the New York Post, from which he also received a undisclosed settlement. He also sued Piedmont College after its president called Jewell a "badge-wearing zealot," according to a 1997 Washington Post article and the school also settled for an unspecified amount.
'Richard Jewell' opens with dismal $5 million haul amid controversy over depiction of reporter trading sex for a scoop. "Richard Jewell" garnered only $5 million during its domestic debut. The film was expected to haul in around $10 million. Prior to its release, the film sparked a heated battle between Warner Bros.
After being exonerated, Richard Jewell, in real life, filed a defamation suit against the Atlanta Journal-Constitution newspaper and a host of other American news organizations. … The article says that Jewell was questioned by FBI agents but was never charged and the Justice Department ultimately apologized to him.
THIS IS INTERESTING: Question: How do you disable gem upgrades in Path of Exile?
The cause of death was acute morphine toxicity, according to the GBI medical examiner, who was unable to determine whether the overdose was intentional or accidental. … Cherokee Coroner Earl Darby said Scruggs appeared to have died peacefully in her sleep.
Rudolph was captured in May 2003 while "rummaging through a trash bin behind a rural grocery [store] in Murphy, North Carolina." He'd already made the FBI's top 10 fugitive list.
The film shows Scruggs, portrayed by Olivia Wilde, sleeping with an FBI agent, played by Jon Hamm, to get the story. Scruggs died in 2001 at the age of 42. The paper has maintained that there is no evidence that Scruggs slept with anyone involved in the Jewell investigation.
Deceased (1962–2007)
The blast directly killed one person and injured 111 others; another person later died of a heart attack. It was the first of four bombings committed by Eric Rudolph. Security guard Richard Jewell discovered the bomb before detonation and began clearing spectators out of the park.
The drama tells the story of the 1996 Olympic Park bombing in Atlanta and two of its suspects: Richard Jewell (played by Cameron Britton) and Eric Rudolph (Jack Huston). Like every drama based on true events, Manhunt: Deadly Games does take some liberties with the real-life story.
A Justice Department investigation of the FBI's conduct found the FBI had tried to manipulate Jewell into waiving his constitutional rights by telling him he was taking part in a training film about bomb detection, although the report concluded "no intentional violation of Mr.
THIS IS INTERESTING: Question: What gemstones go with rose gold?
Controversy. The film came under fire for its portrayal of The Atlanta Journal-Constitution reporter Kathy Scruggs, who had died of a prescription drug overdose in 2001. Criticism was directed at the film for depicting her as offering to engage in sex with an FBI agent in return for confidential information.
Clint Eastwood's Richard Jewell tells the true story of the titular Atlanta security guard who became a prime suspect in the bombing at the 1996 Olympics before ultimately being cleared by law enforcement. … "There has never been any evidence that this is how Kathy got the story," he told The Hollywood Reporter.
Scruggs died in 2001 from a prescription drug overdose, due, in part, to a chronic back problem, still troubled by the repercussions of her Jewell reporting. In a feature last month, the Atlanta Journal Constitution reported that Scruggs was disturbed by a lawsuit naming the AJC.
In one scene, she is doing cocaine with a cop at her home. In another, she's injecting drugs confiscated at a crime scene and given to her by an officer at a club. Furr, who was also critical of the "Richard Jewell" movie, told Oxygen.com that Scruggs didn't do recreational drugs.
When was jewelry invented?
Why did Lil Uzi Vert diamond in the forehead?
Best answer: How do you unlock the extreme Emerald Weapon?
Quick Answer: Where are yellow diamonds mined?
Which class does the necklace represent?
Does Princess cut diamond look bigger?
You asked: Should I upgrade from Sapphire preferred to reserve?


text:
using namespace llvm;

#define DEBUG_TYPE "mc"

namespace {

// Went we ceate the indirect function table we start at 1, so that there is
// and emtpy slot at 0 and therefore calling a null function pointer will trap.
static const uint32_t InitialTableOffset = 1;

// For patching purposes, we need to remember where each section starts, both
// for patching up the section size field, and for patching up references to
// locations within the section.
struct SectionBookkeeping {
  // Where the size of the section is written.
  uint64_t SizeOffset;
  // Where the section header ends (without custom section name).
  uint64_t PayloadOffset;
  // Where the contents of the section starts.
  uint64_t ContentsOffset;
  uint32_t Index;
};

// The signature of a wasm function or event, in a struct capable of being used
// as a DenseMap key.
// TODO: Consider using wasm::WasmSignature directly instead.
struct WasmSignature {
  // Support empty and tombstone instances, needed by DenseMap.
  enum { Plain, Empty, Tombstone } State = Plain;

  // The return types of the function.
  SmallVector<wasm::ValType, 1> Returns;

  // The parameter types of the function.
  SmallVector<wasm::ValType, 4> Params;

  bool operator==(const WasmSignature &Other) const {
    return State == Other.State && Returns == Other.Returns &&
           Params == Other.Params;
  }
};

// Traits for using WasmSignature in a DenseMap.
struct WasmSignatureDenseMapInfo {
  static WasmSignature getEmptyKey() {
    WasmSignature Sig;
    Sig.State = WasmSignature::Empty;
    return Sig;
  }
  static WasmSignature getTombstoneKey() {
    WasmSignature Sig;
    Sig.State = WasmSignature::Tombstone;
    return Sig;
  }
  static unsigned getHashValue(const WasmSignature &Sig) {
    uintptr_t Value = Sig.State;
    for (wasm::ValType Ret : Sig.Returns)
      Value += DenseMapInfo<uint32_t>::getHashValue(uint32_t(Ret));
    for (wasm::ValType Param : Sig.Params)
      Value += DenseMapInfo<uint32_t>::getHashValue(uint32_t(Param));
    return Value;
  }
  static bool isEqual(const WasmSignature &LHS, const WasmSignature &RHS) {
    return LHS == RHS;
  }
};

// A wasm data segment.  A wasm binary contains only a single data section
// but that can contain many segments, each with their own virtual location
// in memory.  Each MCSection data created by llvm is modeled as its own
// wasm data segment.
struct WasmDataSegment {
  MCSectionWasm *Section;
  StringRef Name;
  uint32_t InitFlags;
  uint32_t Offset;
  uint32_t Alignment;
  uint32_t LinkerFlags;
  SmallVector<char, 4> Data;
};

// A wasm function to be written into the function section.
struct WasmFunction {
  uint32_t SigIndex;
  const MCSymbolWasm *Sym;
};

// A wasm global to be written into the global section.
struct WasmGlobal {
  wasm::WasmGlobalType Type;
  uint64_t InitialValue;
};

// Information about a single item which is part of a COMDAT.  For each data
// segment or function which is in the COMDAT, there is a corresponding
// WasmComdatEntry.
struct WasmComdatEntry {
  unsigned Kind;
  uint32_t Index;
};

// Information about a single relocation.
struct WasmRelocationEntry {
  uint64_t Offset;                   // Where is the relocation.
  const MCSymbolWasm *Symbol;        // The symbol to relocate with.
  int64_t Addend;                    // A value to add to the symbol.
  unsigned Type;                     // The type of the relocation.
  const MCSectionWasm *FixupSection; // The section the relocation is targeting.

  WasmRelocationEntry(uint64_t Offset, const MCSymbolWasm *Symbol,
                      int64_t Addend, unsigned Type,
                      const MCSectionWasm *FixupSection)
      : Offset(Offset), Symbol(Symbol), Addend(Addend), Type(Type),
        FixupSection(FixupSection) {}

  bool hasAddend() const { return wasm::relocTypeHasAddend(Type); }

  void print(raw_ostream &Out) const {
    Out << wasm::relocTypetoString(Type) << " Off=" << Offset
        << ", Sym=" << *Symbol << ", Addend=" << Addend
        << ", FixupSection=" << FixupSection->getSectionName();
  }

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
#endif
};

static const uint32_t InvalidIndex = -1;

struct WasmCustomSection {

  StringRef Name;
  MCSectionWasm *Section;

  uint32_t OutputContentsOffset;
  uint32_t OutputIndex;

  WasmCustomSection(StringRef Name, MCSectionWasm *Section)
      : Name(Name), Section(Section), OutputContentsOffset(0),
        OutputIndex(InvalidIndex) {}
};

#if !defined(NDEBUG)
raw_ostream &operator<<(raw_ostream &OS, const WasmRelocationEntry &Rel) {
  Rel.print(OS);
  return OS;
}
#endif

// Write X as an (unsigned) LEB value at offset Offset in Stream, padded
// to allow patching.
static void writePatchableLEB(raw_pwrite_stream &Stream, uint32_t X,
                              uint64_t Offset) {
  uint8_t Buffer[5];
  unsigned SizeLen = encodeULEB128(X, Buffer, 5);
  assert(SizeLen == 5);
  Stream.pwrite((char *)Buffer, SizeLen, Offset);
}

// Write X as an signed LEB value at offset Offset in Stream, padded
// to allow patching.
static void writePatchableSLEB(raw_pwrite_stream &Stream, int32_t X,
                               uint64_t Offset) {
  uint8_t Buffer[5];
  unsigned SizeLen = encodeSLEB128(X, Buffer, 5);
  assert(SizeLen == 5);
  Stream.pwrite((char *)Buffer, SizeLen, Offset);
}

// Write X as a plain integer value at offset Offset in Stream.
static void writeI32(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
  uint8_t Buffer[4];
  support::endian::write32le(Buffer, X);
  Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset);
}

class WasmObjectWriter : public MCObjectWriter {
  support::endian::Writer W;

  /// The target specific Wasm writer instance.
  std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter;

  // Relocations for fixing up references in the code section.
  std::vector<WasmRelocationEntry> CodeRelocations;
  uint32_t CodeSectionIndex;

  // Relocations for fixing up references in the data section.
  std::vector<WasmRelocationEntry> DataRelocations;
  uint32_t DataSectionIndex;

  // Index values to use for fixing up call_indirect type indices.
  // Maps function symbols to the index of the type of the function
  DenseMap<const MCSymbolWasm *, uint32_t> TypeIndices;
  // Maps function symbols to the table element index space. Used
  // for TABLE_INDEX relocation types (i.e. address taken functions).
  DenseMap<const MCSymbolWasm *, uint32_t> TableIndices;
  // Maps function/global symbols to the function/global/event/section index
  // space.
  DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices;
  DenseMap<const MCSymbolWasm *, uint32_t> GOTIndices;
  // Maps data symbols to the Wasm segment and offset/size with the segment.
  DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations;

  // Stores output data (index, relocations, content offset) for custom
  // section.
  std::vector<WasmCustomSection> CustomSections;
  std::unique_ptr<WasmCustomSection> ProducersSection;
  std::unique_ptr<WasmCustomSection> TargetFeaturesSection;
  // Relocations for fixing up references in the custom sections.
  DenseMap<const MCSectionWasm *, std::vector<WasmRelocationEntry>>
      CustomSectionsRelocations;

  // Map from section to defining function symbol.
  DenseMap<const MCSection *, const MCSymbol *> SectionFunctions;

  DenseMap<WasmSignature, uint32_t, WasmSignatureDenseMapInfo> SignatureIndices;
  SmallVector<WasmSignature, 4> Signatures;
  SmallVector<WasmDataSegment, 4> DataSegments;
  unsigned NumFunctionImports = 0;
  unsigned NumGlobalImports = 0;
  unsigned NumEventImports = 0;
  uint32_t SectionCount = 0;

  // TargetObjectWriter wrappers.
  bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
  bool isEmscripten() const { return TargetObjectWriter->isEmscripten(); }

  void startSection(SectionBookkeeping &Section, unsigned SectionId);
  void startCustomSection(SectionBookkeeping &Section, StringRef Name);
  void endSection(SectionBookkeeping &Section);

public:
  WasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
                   raw_pwrite_stream &OS)
      : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {}

private:
  void reset() override {
    CodeRelocations.clear();
    DataRelocations.clear();
    TypeIndices.clear();
    WasmIndices.clear();
    GOTIndices.clear();
    TableIndices.clear();
    DataLocations.clear();
    CustomSections.clear();
    ProducersSection.reset();
    TargetFeaturesSection.reset();
    CustomSectionsRelocations.clear();
    SignatureIndices.clear();
    Signatures.clear();
    DataSegments.clear();
    SectionFunctions.clear();
    NumFunctionImports = 0;
    NumGlobalImports = 0;
    MCObjectWriter::reset();
  }

  void writeHeader(const MCAssembler &Asm);

  void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
                        const MCFragment *Fragment, const MCFixup &Fixup,
                        MCValue Target, uint64_t &FixedValue) override;

  void executePostLayoutBinding(MCAssembler &Asm,
                                const MCAsmLayout &Layout) override;

  uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;

  void writeString(const StringRef Str) {
    encodeULEB128(Str.size(), W.OS);
    W.OS << Str;
  }

  void writeValueType(wasm::ValType Ty) { W.OS << static_cast<char>(Ty); }

  void writeTypeSection(ArrayRef<WasmSignature> Signatures);
  void writeImportSection(ArrayRef<wasm::WasmImport> Imports, uint32_t DataSize,
                          uint32_t NumElements);
  void writeFunctionSection(ArrayRef<WasmFunction> Functions);
  void writeExportSection(ArrayRef<wasm::WasmExport> Exports);
  void writeElemSection(ArrayRef<uint32_t> TableElems);
  void writeDataCountSection();
  void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
                        ArrayRef<WasmFunction> Functions);
  void writeDataSection();
  void writeEventSection(ArrayRef<wasm::WasmEventType> Events);
  void writeRelocSection(uint32_t SectionIndex, StringRef Name,
                         std::vector<WasmRelocationEntry> &Relocations);
  void writeLinkingMetaDataSection(
      ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
      ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
      const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats);
  void writeCustomSection(WasmCustomSection &CustomSection,
                          const MCAssembler &Asm, const MCAsmLayout &Layout);
  void writeCustomRelocSections();
  void
  updateCustomSectionRelocations(const SmallVector<WasmFunction, 4> &Functions,
                                 const MCAsmLayout &Layout);

  uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry);
  void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
                        uint64_t ContentsOffset);

  uint32_t getRelocationIndexValue(const WasmRelocationEntry &RelEntry);
  uint32_t getFunctionType(const MCSymbolWasm &Symbol);
  uint32_t getEventType(const MCSymbolWasm &Symbol);
  void registerFunctionType(const MCSymbolWasm &Symbol);
  void registerEventType(const MCSymbolWasm &Symbol);
};

} // end anonymous namespace

// Write out a section header and a patchable section size field.
void WasmObjectWriter::startSection(SectionBookkeeping &Section,
                                    unsigned SectionId) {
  LLVM_DEBUG(dbgs() << "startSection " << SectionId << "\n");
  W.OS << char(SectionId);

  Section.SizeOffset = W.OS.tell();

  // The section size. We don't know the size yet, so reserve enough space
  // for any 32-bit value; we'll patch it later.
  encodeULEB128(0, W.OS, 5);

  // The position where the section starts, for measuring its size.
  Section.ContentsOffset = W.OS.tell();
  Section.PayloadOffset = W.OS.tell();
  Section.Index = SectionCount++;
}

void WasmObjectWriter::startCustomSection(SectionBookkeeping &Section,
                                          StringRef Name) {
  LLVM_DEBUG(dbgs() << "startCustomSection " << Name << "\n");
  startSection(Section, wasm::WASM_SEC_CUSTOM);

  // The position where the section header ends, for measuring its size.
  Section.PayloadOffset = W.OS.tell();

  // Custom sections in wasm also have a string identifier.
  writeString(Name);

  // The position where the custom section starts.
  Section.ContentsOffset = W.OS.tell();
}

// Now that the section is complete and we know how big it is, patch up the
// section size field at the start of the section.
void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
  uint64_t Size = W.OS.tell();
  // /dev/null doesn't support seek/tell and can report offset of 0.
  // Simply skip this patching in that case.
  if (!Size)
    return;

  Size -= Section.PayloadOffset;
  if (uint32_t(Size) != Size)
    report_fatal_error("section size does not fit in a uint32_t");

  LLVM_DEBUG(dbgs() << "endSection size=" << Size << "\n");

  // Write the final section size to the payload_len field, which follows
  // the section id byte.
  writePatchableLEB(static_cast<raw_pwrite_stream &>(W.OS), Size,
                    Section.SizeOffset);
}

// Emit the Wasm header.
void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
  W.OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic));
  W.write<uint32_t>(wasm::WasmVersion);
}

void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
                                                const MCAsmLayout &Layout) {
  // Build a map of sections to the function that defines them, for use
  // in recordRelocation.
  for (const MCSymbol &S : Asm.symbols()) {
    const auto &WS = static_cast<const MCSymbolWasm &>(S);
    if (WS.isDefined() && WS.isFunction() && !WS.isVariable()) {
      const auto &Sec = static_cast<const MCSectionWasm &>(S.getSection());
      auto Pair = SectionFunctions.insert(std::make_pair(&Sec, &S));
      if (!Pair.second)
        report_fatal_error("section already has a defining function: " +
                           Sec.getSectionName());
    }
  }
}

void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
                                        const MCAsmLayout &Layout,
                                        const MCFragment *Fragment,
                                        const MCFixup &Fixup, MCValue Target,
                                        uint64_t &FixedValue) {
  // The WebAssembly backend should never generate FKF_IsPCRel fixups
  assert(!(Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags &
           MCFixupKindInfo::FKF_IsPCRel));

  const auto &FixupSection = cast<MCSectionWasm>(*Fragment->getParent());
  uint64_t C = Target.getConstant();
  uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
  MCContext &Ctx = Asm.getContext();

  // The .init_array isn't translated as data, so don't do relocations in it.
  if (FixupSection.getSectionName().startswith(".init_array"))
    return;

  if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
    // To get here the A - B expression must have failed evaluateAsRelocatable.
    // This means either A or B must be undefined and in WebAssembly we can't
    // support either of those cases.
    const auto &SymB = cast<MCSymbolWasm>(RefB->getSymbol());
    Ctx.reportError(
        Fixup.getLoc(),
        Twine("symbol '") + SymB.getName() +
            "': unsupported subtraction expression used in relocation.");
    return;
  }

  // We either rejected the fixup or folded B into C at this point.
  const MCSymbolRefExpr *RefA = Target.getSymA();
  const auto *SymA = cast<MCSymbolWasm>(&RefA->getSymbol());

  if (SymA->isVariable()) {
    const MCExpr *Expr = SymA->getVariableValue();
    const auto *Inner = cast<MCSymbolRefExpr>(Expr);
    if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF)
      llvm_unreachable("weakref used in reloc not yet implemented");
  }

  // Put any constant offset in an addend. Offsets can be negative, and
  // LLVM expects wrapping, in contrast to wasm's immediates which can't
  // be negative and don't wrap.
  FixedValue = 0;

  unsigned Type = TargetObjectWriter->getRelocType(Target, Fixup);

  // Absolute offset within a section or a function.
  // Currently only supported for for metadata sections.
  // See: test/MC/WebAssembly/blockaddress.ll
  if (Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
      Type == wasm::R_WASM_SECTION_OFFSET_I32) {
    if (!FixupSection.getKind().isMetadata())
      report_fatal_error("relocations for function or section offsets are "
                         "only supported in metadata sections");

    const MCSymbol *SectionSymbol = nullptr;
    const MCSection &SecA = SymA->getSection();
    if (SecA.getKind().isText())
      SectionSymbol = SectionFunctions.find(&SecA)->second;
    else
      SectionSymbol = SecA.getBeginSymbol();
    if (!SectionSymbol)
      report_fatal_error("section symbol is required for relocation");

    C += Layout.getSymbolOffset(*SymA);
    SymA = cast<MCSymbolWasm>(SectionSymbol);
  }

  // Relocation other than R_WASM_TYPE_INDEX_LEB are required to be
  // against a named symbol.
  if (Type != wasm::R_WASM_TYPE_INDEX_LEB) {
    if (SymA->getName().empty())
      report_fatal_error("relocations against un-named temporaries are not yet "
                         "supported by wasm");

    SymA->setUsedInReloc();
  }

  if (RefA->getKind() == MCSymbolRefExpr::VK_GOT)
    SymA->setUsedInGOT();

  WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection);
  LLVM_DEBUG(dbgs() << "WasmReloc: " << Rec << "\n");

  if (FixupSection.isWasmData()) {
    DataRelocations.push_back(Rec);
  } else if (FixupSection.getKind().isText()) {
    CodeRelocations.push_back(Rec);
  } else if (FixupSection.getKind().isMetadata()) {
    CustomSectionsRelocations[&FixupSection].push_back(Rec);
  } else {
    llvm_unreachable("unexpected section type");
  }
}

static const MCSymbolWasm *resolveSymbol(const MCSymbolWasm &Symbol) {
  const MCSymbolWasm* Ret = &Symbol;
  while (Ret->isVariable()) {
    const MCExpr *Expr = Ret->getVariableValue();
    auto *Inner = cast<MCSymbolRefExpr>(Expr);
    Ret = cast<MCSymbolWasm>(&Inner->getSymbol());
  }
  return Ret;
}

// Compute a value to write into the code at the location covered
// by RelEntry. This value isn't used by the static linker; it just serves
// to make the object format more readable and more likely to be directly
// useable.
uint32_t
WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
  if (RelEntry.Type == wasm::R_WASM_GLOBAL_INDEX_LEB && !RelEntry.Symbol->isGlobal()) {
    assert(GOTIndices.count(RelEntry.Symbol) > 0 && "symbol not found in GOT index space");
    return GOTIndices[RelEntry.Symbol];
  }

  switch (RelEntry.Type) {
  case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
  case wasm::R_WASM_TABLE_INDEX_SLEB:
  case wasm::R_WASM_TABLE_INDEX_I32: {
    // Provisional value is table address of the resolved symbol itself
    const MCSymbolWasm *Sym = resolveSymbol(*RelEntry.Symbol);
    assert(Sym->isFunction());
    return TableIndices[Sym];
  }
  case wasm::R_WASM_TYPE_INDEX_LEB:
    // Provisional value is same as the index
    return getRelocationIndexValue(RelEntry);
  case wasm::R_WASM_FUNCTION_INDEX_LEB:
  case wasm::R_WASM_GLOBAL_INDEX_LEB:
  case wasm::R_WASM_EVENT_INDEX_LEB:
    // Provisional value is function/global/event Wasm index
    assert(WasmIndices.count(RelEntry.Symbol) > 0 && "symbol not found in wasm index space");
    return WasmIndices[RelEntry.Symbol];
  case wasm::R_WASM_FUNCTION_OFFSET_I32:
  case wasm::R_WASM_SECTION_OFFSET_I32: {
    const auto &Section =
        static_cast<const MCSectionWasm &>(RelEntry.Symbol->getSection());
    return Section.getSectionOffset() + RelEntry.Addend;
  }
  case wasm::R_WASM_MEMORY_ADDR_LEB:
  case wasm::R_WASM_MEMORY_ADDR_I32:
  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
  case wasm::R_WASM_MEMORY_ADDR_SLEB: {
    // Provisional value is address of the global
    const MCSymbolWasm *Sym = resolveSymbol(*RelEntry.Symbol);
    // For undefined symbols, use zero
    if (!Sym->isDefined())
      return 0;
    const wasm::WasmDataReference &Ref = DataLocations[Sym];
    const WasmDataSegment &Segment = DataSegments[Ref.Segment];
    // Ignore overflow. LLVM allows address arithmetic to silently wrap.
    return Segment.Offset + Ref.Offset + RelEntry.Addend;
  }
  default:
    llvm_unreachable("invalid relocation type");
  }
}

static void addData(SmallVectorImpl<char> &DataBytes,
                    MCSectionWasm &DataSection) {
  LLVM_DEBUG(errs() << "addData: " << DataSection.getSectionName() << "\n");

  DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));

  for (const MCFragment &Frag : DataSection) {
    if (Frag.hasInstructions())
      report_fatal_error("only data supported in data sections");

    if (auto *Align = dyn_cast<MCAlignFragment>(&Frag)) {
      if (Align->getValueSize() != 1)
        report_fatal_error("only byte values supported for alignment");
      // If nops are requested, use zeros, as this is the data section.
      uint8_t Value = Align->hasEmitNops() ? 0 : Align->getValue();
      uint64_t Size =
          std::min<uint64_t>(alignTo(DataBytes.size(), Align->getAlignment()),
                             DataBytes.size() + Align->getMaxBytesToEmit());
      DataBytes.resize(Size, Value);
    } else if (auto *Fill = dyn_cast<MCFillFragment>(&Frag)) {
      int64_t NumValues;
      if (!Fill->getNumValues().evaluateAsAbsolute(NumValues))
        llvm_unreachable("The fill should be an assembler constant");
      DataBytes.insert(DataBytes.end(), Fill->getValueSize() * NumValues,
                       Fill->getValue());
    } else if (auto *LEB = dyn_cast<MCLEBFragment>(&Frag)) {
      const SmallVectorImpl<char> &Contents = LEB->getContents();
      DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
    } else {
      const auto &DataFrag = cast<MCDataFragment>(Frag);
      const SmallVectorImpl<char> &Contents = DataFrag.getContents();
      DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
    }
  }

  LLVM_DEBUG(dbgs() << "addData -> " << DataBytes.size() << "\n");
}

uint32_t
WasmObjectWriter::getRelocationIndexValue(const WasmRelocationEntry &RelEntry) {
  if (RelEntry.Type == wasm::R_WASM_TYPE_INDEX_LEB) {
    if (!TypeIndices.count(RelEntry.Symbol))
      report_fatal_error("symbol not found in type index space: " +
                         RelEntry.Symbol->getName());
    return TypeIndices[RelEntry.Symbol];
  }

  return RelEntry.Symbol->getIndex();
}

// Apply the portions of the relocation records that we can handle ourselves
// directly.
void WasmObjectWriter::applyRelocations(
    ArrayRef<WasmRelocationEntry> Relocations, uint64_t ContentsOffset) {
  auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
  for (const WasmRelocationEntry &RelEntry : Relocations) {
    uint64_t Offset = ContentsOffset +
                      RelEntry.FixupSection->getSectionOffset() +
                      RelEntry.Offset;

    LLVM_DEBUG(dbgs() << "applyRelocation: " << RelEntry << "\n");
    uint32_t Value = getProvisionalValue(RelEntry);

    switch (RelEntry.Type) {
    case wasm::R_WASM_FUNCTION_INDEX_LEB:
    case wasm::R_WASM_TYPE_INDEX_LEB:
    case wasm::R_WASM_GLOBAL_INDEX_LEB:
    case wasm::R_WASM_MEMORY_ADDR_LEB:
    case wasm::R_WASM_EVENT_INDEX_LEB:
      writePatchableLEB(Stream, Value, Offset);
      break;
    case wasm::R_WASM_TABLE_INDEX_I32:
    case wasm::R_WASM_MEMORY_ADDR_I32:
    case wasm::R_WASM_FUNCTION_OFFSET_I32:
    case wasm::R_WASM_SECTION_OFFSET_I32:
      writeI32(Stream, Value, Offset);
      break;
    case wasm::R_WASM_TABLE_INDEX_SLEB:
    case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
    case wasm::R_WASM_MEMORY_ADDR_SLEB:
    case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
      writePatchableSLEB(Stream, Value, Offset);
      break;
    default:
      llvm_unreachable("invalid relocation type");
    }
  }
}

void WasmObjectWriter::writeTypeSection(ArrayRef<WasmSignature> Signatures) {
  if (Signatures.empty())
    return;

  SectionBookkeeping Section;
  startSection(Section, wasm::WASM_SEC_TYPE);

  encodeULEB128(Signatures.size(), W.OS);

  for (const WasmSignature &Sig : Signatures) {
    W.OS << char(wasm::WASM_TYPE_FUNC);
    encodeULEB128(Sig.Params.size(), W.OS);
    for (wasm::ValType Ty : Sig.Params)
      writeValueType(Ty);
    encodeULEB128(Sig.Returns.size(), W.OS);
    for (wasm::ValType Ty : Sig.Returns)
      writeValueType(Ty);
  }

  endSection(Section);
}

void WasmObjectWriter::writeImportSection(ArrayRef<wasm::WasmImport> Imports,
                                          uint32_t DataSize,
                                          uint32_t NumElements) {
  if (Imports.empty())
    return;

  uint32_t NumPages = (DataSize + wasm::WasmPageSize - 1) / wasm::WasmPageSize;

  SectionBookkeeping Section;
  startSection(Section, wasm::WASM_SEC_IMPORT);

  encodeULEB128(Imports.size(), W.OS);
  for (const wasm::WasmImport &Import : Imports) {
    writeString(Import.Module);
    writeString(Import.Field);
    W.OS << char(Import.Kind);

    switch (Import.Kind) {
    case wasm::WASM_EXTERNAL_FUNCTION:
      encodeULEB128(Import.SigIndex, W.OS);
      break;
    case wasm::WASM_EXTERNAL_GLOBAL:
      W.OS << char(Import.Global.Type);
      W.OS << char(Import.Global.Mutable ? 1 : 0);
      break;
    case wasm::WASM_EXTERNAL_MEMORY:
      encodeULEB128(0, W.OS);        // flags
      encodeULEB128(NumPages, W.OS); // initial
      break;
    case wasm::WASM_EXTERNAL_TABLE:
      W.OS << char(Import.Table.ElemType);
      encodeULEB128(0, W.OS);           // flags
      encodeULEB128(NumElements, W.OS); // initial
      break;
    case wasm::WASM_EXTERNAL_EVENT:
      encodeULEB128(Import.Event.Attribute, W.OS);
      encodeULEB128(Import.Event.SigIndex, W.OS);
      break;
    default:
      llvm_unreachable("unsupported import kind");
    }
  }

  endSection(Section);
}

void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) {
  if (Functions.empty())
    return;

  SectionBookkeeping Section;
  startSection(Section, wasm::WASM_SEC_FUNCTION);

  encodeULEB128(Functions.size(), W.OS);
  for (const WasmFunction &Func : Functions)
    encodeULEB128(Func.SigIndex, W.OS);

  endSection(Section);
}

void WasmObjectWriter::writeEventSection(ArrayRef<wasm::WasmEventType> Events) {
  if (Events.empty())
    return;

  SectionBookkeeping Section;
  startSection(Section, wasm::WASM_SEC_EVENT);

  encodeULEB128(Events.size(), W.OS);
  for (const wasm::WasmEventType &Event : Events) {
    encodeULEB128(Event.Attribute, W.OS);
    encodeULEB128(Event.SigIndex, W.OS);
  }

  endSection(Section);
}

void WasmObjectWriter::writeExportSection(ArrayRef<wasm::WasmExport> Exports) {
  if (Exports.empty())
    return;

  SectionBookkeeping Section;
  startSection(Section, wasm::WASM_SEC_EXPORT);

  encodeULEB128(Exports.size(), W.OS);
  for (const wasm::WasmExport &Export : Exports) {
    writeString(Export.Name);
    W.OS << char(Export.Kind);
    encodeULEB128(Export.Index, W.OS);
  }

  endSection(Section);
}

void WasmObjectWriter::writeElemSection(ArrayRef<uint32_t> TableElems) {
  if (TableElems.empty())
    return;

  SectionBookkeeping Section;
  startSection(Section, wasm::WASM_SEC_ELEM);

  encodeULEB128(1, W.OS); // number of "segments"
  encodeULEB128(0, W.OS); // the table index

  // init expr for starting offset
  W.OS << char(wasm::WASM_OPCODE_I32_CONST);
  encodeSLEB128(InitialTableOffset, W.OS);
  W.OS << char(wasm::WASM_OPCODE_END);

  encodeULEB128(TableElems.size(), W.OS);
  for (uint32_t Elem : TableElems)
    encodeULEB128(Elem, W.OS);

  endSection(Section);
}

void WasmObjectWriter::writeDataCountSection() {
  if (DataSegments.empty())
    return;

  SectionBookkeeping Section;
  startSection(Section, wasm::WASM_SEC_DATACOUNT);
  encodeULEB128(DataSegments.size(), W.OS);
  endSection(Section);
}

void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm,
                                        const MCAsmLayout &Layout,
                                        ArrayRef<WasmFunction> Functions) {
  if (Functions.empty())
    return;

  SectionBookkeeping Section;
  startSection(Section, wasm::WASM_SEC_CODE);
  CodeSectionIndex = Section.Index;

  encodeULEB128(Functions.size(), W.OS);

  for (const WasmFunction &Func : Functions) {
    auto &FuncSection = static_cast<MCSectionWasm &>(Func.Sym->getSection());

    int64_t Size = 0;
    if (!Func.Sym->getSize()->evaluateAsAbsolute(Size, Layout))
      report_fatal_error(".size expression must be evaluatable");

    encodeULEB128(Size, W.OS);
    FuncSection.setSectionOffset(W.OS.tell() - Section.ContentsOffset);
    Asm.writeSectionData(W.OS, &FuncSection, Layout);
  }

  // Apply fixups.
  applyRelocations(CodeRelocations, Section.ContentsOffset);

  endSection(Section);
}

void WasmObjectWriter::writeDataSection() {
  if (DataSegments.empty())
    return;

  SectionBookkeeping Section;
  startSection(Section, wasm::WASM_SEC_DATA);
  DataSectionIndex = Section.Index;

  encodeULEB128(DataSegments.size(), W.OS); // count

  for (const WasmDataSegment &Segment : DataSegments) {
    encodeULEB128(Segment.InitFlags, W.OS); // flags
    if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX)
      encodeULEB128(0, W.OS); // memory index
    if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) {
      W.OS << char(wasm::WASM_OPCODE_I32_CONST);
      encodeSLEB128(Segment.Offset, W.OS); // offset
      W.OS << char(wasm::WASM_OPCODE_END);
    }
    encodeULEB128(Segment.Data.size(), W.OS); // size
    Segment.Section->setSectionOffset(W.OS.tell() - Section.ContentsOffset);
    W.OS << Segment.Data; // data
  }

  // Apply fixups.
  applyRelocations(DataRelocations, Section.ContentsOffset);

  endSection(Section);
}

void WasmObjectWriter::writeRelocSection(
    uint32_t SectionIndex, StringRef Name,
    std::vector<WasmRelocationEntry> &Relocs) {
  // See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
  // for descriptions of the reloc sections.

  if (Relocs.empty())
    return;

  // First, ensure the relocations are sorted in offset order.  In general they
  // should already be sorted since `recordRelocation` is called in offset
  // order, but for the code section we combine many MC sections into single
  // wasm section, and this order is determined by the order of Asm.Symbols()
  // not the sections order.
  llvm::stable_sort(
      Relocs, [](const WasmRelocationEntry &A, const WasmRelocationEntry &B) {
        return (A.Offset + A.FixupSection->getSectionOffset()) <
               (B.Offset + B.FixupSection->getSectionOffset());
      });

  SectionBookkeeping Section;
  startCustomSection(Section, std::string("reloc.") + Name.str());

  encodeULEB128(SectionIndex, W.OS);
  encodeULEB128(Relocs.size(), W.OS);
  for (const WasmRelocationEntry &RelEntry : Relocs) {
    uint64_t Offset =
        RelEntry.Offset + RelEntry.FixupSection->getSectionOffset();
    uint32_t Index = getRelocationIndexValue(RelEntry);

    W.OS << char(RelEntry.Type);
    encodeULEB128(Offset, W.OS);
    encodeULEB128(Index, W.OS);
    if (RelEntry.hasAddend())
      encodeSLEB128(RelEntry.Addend, W.OS);
  }

  endSection(Section);
}

void WasmObjectWriter::writeCustomRelocSections() {
  for (const auto &Sec : CustomSections) {
    auto &Relocations = CustomSectionsRelocations[Sec.Section];
    writeRelocSection(Sec.OutputIndex, Sec.Name, Relocations);
  }
}

void WasmObjectWriter::writeLinkingMetaDataSection(
    ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
    ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
    const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats) {
  SectionBookkeeping Section;
  startCustomSection(Section, "linking");
  encodeULEB128(wasm::WasmMetadataVersion, W.OS);

  SectionBookkeeping SubSection;
  if (SymbolInfos.size() != 0) {
    startSection(SubSection, wasm::WASM_SYMBOL_TABLE);
    encodeULEB128(SymbolInfos.size(), W.OS);
    for (const wasm::WasmSymbolInfo &Sym : SymbolInfos) {
      encodeULEB128(Sym.Kind, W.OS);
      encodeULEB128(Sym.Flags, W.OS);
      switch (Sym.Kind) {
      case wasm::WASM_SYMBOL_TYPE_FUNCTION:
      case wasm::WASM_SYMBOL_TYPE_GLOBAL:
      case wasm::WASM_SYMBOL_TYPE_EVENT:
        encodeULEB128(Sym.ElementIndex, W.OS);
        if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
            (Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
          writeString(Sym.Name);
        break;
      case wasm::WASM_SYMBOL_TYPE_DATA:
        writeString(Sym.Name);
        if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
          encodeULEB128(Sym.DataRef.Segment, W.OS);
          encodeULEB128(Sym.DataRef.Offset, W.OS);
          encodeULEB128(Sym.DataRef.Size, W.OS);
        }
        break;
      case wasm::WASM_SYMBOL_TYPE_SECTION: {
        const uint32_t SectionIndex =
            CustomSections[Sym.ElementIndex].OutputIndex;
        encodeULEB128(SectionIndex, W.OS);
        break;
      }
      default:
        llvm_unreachable("unexpected kind");
      }
    }
    endSection(SubSection);
  }

  if (DataSegments.size()) {
    startSection(SubSection, wasm::WASM_SEGMENT_INFO);
    encodeULEB128(DataSegments.size(), W.OS);
    for (const WasmDataSegment &Segment : DataSegments) {
      writeString(Segment.Name);
      encodeULEB128(Segment.Alignment, W.OS);
      encodeULEB128(Segment.LinkerFlags, W.OS);
    }
    endSection(SubSection);
  }

  if (!InitFuncs.empty()) {
    startSection(SubSection, wasm::WASM_INIT_FUNCS);
    encodeULEB128(InitFuncs.size(), W.OS);
    for (auto &StartFunc : InitFuncs) {
      encodeULEB128(StartFunc.first, W.OS);  // priority
      encodeULEB128(StartFunc.second, W.OS); // function index
    }
    endSection(SubSection);
  }

  if (Comdats.size()) {
    startSection(SubSection, wasm::WASM_COMDAT_INFO);
    encodeULEB128(Comdats.size(), W.OS);
    for (const auto &C : Comdats) {
      writeString(C.first);
      encodeULEB128(0, W.OS); // flags for future use
      encodeULEB128(C.second.size(), W.OS);
      for (const WasmComdatEntry &Entry : C.second) {
        encodeULEB128(Entry.Kind, W.OS);
        encodeULEB128(Entry.Index, W.OS);
      }
    }
    endSection(SubSection);
  }

  endSection(Section);
}

void WasmObjectWriter::writeCustomSection(WasmCustomSection &CustomSection,
                                          const MCAssembler &Asm,
                                          const MCAsmLayout &Layout) {
  SectionBookkeeping Section;
  auto *Sec = CustomSection.Section;
  startCustomSection(Section, CustomSection.Name);

  Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset);
  Asm.writeSectionData(W.OS, Sec, Layout);

  CustomSection.OutputContentsOffset = Section.ContentsOffset;
  CustomSection.OutputIndex = Section.Index;

  endSection(Section);

  // Apply fixups.
  auto &Relocations = CustomSectionsRelocations[CustomSection.Section];
  applyRelocations(Relocations, CustomSection.OutputContentsOffset);
}

uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm &Symbol) {
  assert(Symbol.isFunction());
  assert(TypeIndices.count(&Symbol));
  return TypeIndices[&Symbol];
}

uint32_t WasmObjectWriter::getEventType(const MCSymbolWasm &Symbol) {
  assert(Symbol.isEvent());
  assert(TypeIndices.count(&Symbol));
  return TypeIndices[&Symbol];
}

void WasmObjectWriter::registerFunctionType(const MCSymbolWasm &Symbol) {
  assert(Symbol.isFunction());

  WasmSignature S;
  const MCSymbolWasm *ResolvedSym = resolveSymbol(Symbol);
  if (auto *Sig = ResolvedSym->getSignature()) {
    S.Returns = Sig->Returns;
    S.Params = Sig->Params;
  }

  auto Pair = SignatureIndices.insert(std::make_pair(S, Signatures.size()));
  if (Pair.second)
    Signatures.push_back(S);
  TypeIndices[&Symbol] = Pair.first->second;

  LLVM_DEBUG(dbgs() << "registerFunctionType: " << Symbol
                    << " new:" << Pair.second << "\n");
  LLVM_DEBUG(dbgs() << "  -> type index: " << Pair.first->second << "\n");
}

void WasmObjectWriter::registerEventType(const MCSymbolWasm &Symbol) {
  assert(Symbol.isEvent());

  // TODO Currently we don't generate imported exceptions, but if we do, we
  // should have a way of infering types of imported exceptions.
  WasmSignature S;
  if (auto *Sig = Symbol.getSignature()) {
    S.Returns = Sig->Returns;
    S.Params = Sig->Params;
  }

  auto Pair = SignatureIndices.insert(std::make_pair(S, Signatures.size()));
  if (Pair.second)
    Signatures.push_back(S);
  TypeIndices[&Symbol] = Pair.first->second;

  LLVM_DEBUG(dbgs() << "registerEventType: " << Symbol << " new:" << Pair.second
                    << "\n");
  LLVM_DEBUG(dbgs() << "  -> type index: " << Pair.first->second << "\n");
}

static bool isInSymtab(const MCSymbolWasm &Sym) {
  if (Sym.isUsedInReloc())
    return true;

  if (Sym.isComdat() && !Sym.isDefined())
    return false;

  if (Sym.isTemporary() && Sym.getName().empty())
    return false;

  if (Sym.isTemporary() && Sym.isData() && !Sym.getSize())
    return false;

  if (Sym.isSection())
    return false;

  return true;
}

uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
                                       const MCAsmLayout &Layout) {
  uint64_t StartOffset = W.OS.tell();

  LLVM_DEBUG(dbgs() << "WasmObjectWriter::writeObject\n");

  // Collect information from the available symbols.
  SmallVector<WasmFunction, 4> Functions;
  SmallVector<uint32_t, 4> TableElems;
  SmallVector<wasm::WasmImport, 4> Imports;
  SmallVector<wasm::WasmExport, 4> Exports;
  SmallVector<wasm::WasmEventType, 1> Events;
  SmallVector<wasm::WasmSymbolInfo, 4> SymbolInfos;
  SmallVector<std::pair<uint16_t, uint32_t>, 2> InitFuncs;
  std::map<StringRef, std::vector<WasmComdatEntry>> Comdats;
  uint32_t DataSize = 0;

  // For now, always emit the memory import, since loads and stores are not
  // valid without it. In the future, we could perhaps be more clever and omit
  // it if there are no loads or stores.
  wasm::WasmImport MemImport;
  MemImport.Module = "env";
  MemImport.Field = "__linear_memory";
  MemImport.Kind = wasm::WASM_EXTERNAL_MEMORY;
  Imports.push_back(MemImport);

  // For now, always emit the table section, since indirect calls are not
  // valid without it. In the future, we could perhaps be more clever and omit
  // it if there are no indirect calls.
  wasm::WasmImport TableImport;
  TableImport.Module = "env";
  TableImport.Field = "__indirect_function_table";
  TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
  TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF;
  Imports.push_back(TableImport);

  // Populate SignatureIndices, and Imports and WasmIndices for undefined
  // symbols.  This must be done before populating WasmIndices for defined
  // symbols.
  for (const MCSymbol &S : Asm.symbols()) {
    const auto &WS = static_cast<const MCSymbolWasm &>(S);

    // Register types for all functions, including those with private linkage
    // (because wasm always needs a type signature).
    if (WS.isFunction())
      registerFunctionType(WS);

    if (WS.isEvent())
      registerEventType(WS);

    if (WS.isTemporary())
      continue;

    // If the symbol is not defined in this translation unit, import it.
    if (!WS.isDefined() && !WS.isComdat()) {
      if (WS.isFunction()) {
        wasm::WasmImport Import;
        Import.Module = WS.getImportModule();
        Import.Field = WS.getImportName();
        Import.Kind = wasm::WASM_EXTERNAL_FUNCTION;
        Import.SigIndex = getFunctionType(WS);
        Imports.push_back(Import);
        assert(WasmIndices.count(&WS) == 0);
        WasmIndices[&WS] = NumFunctionImports++;
      } else if (WS.isGlobal()) {
        if (WS.isWeak())
          report_fatal_error("undefined global symbol cannot be weak");

        wasm::WasmImport Import;
        Import.Field = WS.getImportName();
        Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
        Import.Module = WS.getImportModule();
        Import.Global = WS.getGlobalType();
        Imports.push_back(Import);
        assert(WasmIndices.count(&WS) == 0);
        WasmIndices[&WS] = NumGlobalImports++;
      } else if (WS.isEvent()) {
        if (WS.isWeak())
          report_fatal_error("undefined event symbol cannot be weak");

        wasm::WasmImport Import;
        Import.Module = WS.getImportModule();
        Import.Field = WS.getImportName();
        Import.Kind = wasm::WASM_EXTERNAL_EVENT;
        Import.Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION;
        Import.Event.SigIndex = getEventType(WS);
        Imports.push_back(Import);
        assert(WasmIndices.count(&WS) == 0);
        WasmIndices[&WS] = NumEventImports++;
      }
    }
  }

  // Add imports for GOT globals
  for (const MCSymbol &S : Asm.symbols()) {
    const auto &WS = static_cast<const MCSymbolWasm &>(S);
    if (WS.isUsedInGOT()) {
      wasm::WasmImport Import;
      if (WS.isFunction())
        Import.Module = "GOT.func";
      else
        Import.Module = "GOT.mem";
      Import.Field = WS.getName();
      Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
      Import.Global = {wasm::WASM_TYPE_I32, true};
      Imports.push_back(Import);
      assert(GOTIndices.count(&WS) == 0);
      GOTIndices[&WS] = NumGlobalImports++;
    }
  }

  // Populate DataSegments and CustomSections, which must be done before
  // populating DataLocations.
  for (MCSection &Sec : Asm) {
    auto &Section = static_cast<MCSectionWasm &>(Sec);
    StringRef SectionName = Section.getSectionName();

    // .init_array sections are handled specially elsewhere.
    if (SectionName.startswith(".init_array"))
      continue;

    // Code is handled separately
    if (Section.getKind().isText())
      continue;

    if (Section.isWasmData()) {
      uint32_t SegmentIndex = DataSegments.size();
      DataSize = alignTo(DataSize, Section.getAlignment());
      DataSegments.emplace_back();
      WasmDataSegment &Segment = DataSegments.back();
      Segment.Name = SectionName;
      Segment.InitFlags =
          Section.getPassive() ? (uint32_t)wasm::WASM_SEGMENT_IS_PASSIVE : 0;
      Segment.Offset = DataSize;
      Segment.Section = &Section;
      addData(Segment.Data, Section);
      Segment.Alignment = Log2_32(Section.getAlignment());
      Segment.LinkerFlags = 0;
      DataSize += Segment.Data.size();
      Section.setSegmentIndex(SegmentIndex);

      if (const MCSymbolWasm *C = Section.getGroup()) {
        Comdats[C->getName()].emplace_back(
            WasmComdatEntry{wasm::WASM_COMDAT_DATA, SegmentIndex});
      }
    } else {
      // Create custom sections
      assert(Sec.getKind().isMetadata());

      StringRef Name = SectionName;

      // For user-defined custom sections, strip the prefix
      if (Name.startswith(".custom_section."))
        Name = Name.substr(strlen(".custom_section."));

      MCSymbol *Begin = Sec.getBeginSymbol();
      if (Begin) {
        WasmIndices[cast<MCSymbolWasm>(Begin)] = CustomSections.size();
        if (SectionName != Begin->getName())
          report_fatal_error("section name and begin symbol should match: " +
                             Twine(SectionName));
      }

      // Separate out the producers and target features sections
      if (Name == "producers") {
        ProducersSection = std::make_unique<WasmCustomSection>(Name, &Section);
        continue;
      }
      if (Name == "target_features") {
        TargetFeaturesSection =
            std::make_unique<WasmCustomSection>(Name, &Section);
        continue;
      }

      CustomSections.emplace_back(Name, &Section);
    }
  }

  // Populate WasmIndices and DataLocations for defined symbols.
  for (const MCSymbol &S : Asm.symbols()) {
    // Ignore unnamed temporary symbols, which aren't ever exported, imported,
    // or used in relocations.
    if (S.isTemporary() && S.getName().empty())
      continue;

    const auto &WS = static_cast<const MCSymbolWasm &>(S);
    LLVM_DEBUG(
        dbgs() << "MCSymbol: " << toString(WS.getType()) << " '" << S << "'"
               << " isDefined=" << S.isDefined() << " isExternal="
               << S.isExternal() << " isTemporary=" << S.isTemporary()
               << " isWeak=" << WS.isWeak() << " isHidden=" << WS.isHidden()
               << " isVariable=" << WS.isVariable() << "\n");

    if (WS.isVariable())
      continue;
    if (WS.isComdat() && !WS.isDefined())
      continue;

    if (WS.isFunction()) {
      unsigned Index;
      if (WS.isDefined()) {
        if (WS.getOffset() != 0)
          report_fatal_error(
              "function sections must contain one function each");

        if (WS.getSize() == nullptr)
          report_fatal_error(
              "function symbols must have a size set with .size");

        // A definition. Write out the function body.
        Index = NumFunctionImports + Functions.size();
        WasmFunction Func;
        Func.SigIndex = getFunctionType(WS);
        Func.Sym = &WS;
        WasmIndices[&WS] = Index;
        Functions.push_back(Func);

        auto &Section = static_cast<MCSectionWasm &>(WS.getSection());
        if (const MCSymbolWasm *C = Section.getGroup()) {
          Comdats[C->getName()].emplace_back(
              WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index});
        }

        if (WS.hasExportName()) {
          wasm::WasmExport Export;
          Export.Name = WS.getExportName();
          Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
          Export.Index = Index;
          Exports.push_back(Export);
        }
      } else {
        // An import; the index was assigned above.
        Index = WasmIndices.find(&WS)->second;
      }

      LLVM_DEBUG(dbgs() << "  -> function index: " << Index << "\n");

    } else if (WS.isData()) {
      if (!isInSymtab(WS))
        continue;

      if (!WS.isDefined()) {
        LLVM_DEBUG(dbgs() << "  -> segment index: -1"
                          << "\n");
        continue;
      }

      if (!WS.getSize())
        report_fatal_error("data symbols must have a size set with .size: " +
                           WS.getName());

      int64_t Size = 0;
      if (!WS.getSize()->evaluateAsAbsolute(Size, Layout))
        report_fatal_error(".size expression must be evaluatable");

      auto &DataSection = static_cast<MCSectionWasm &>(WS.getSection());
      if (!DataSection.isWasmData())
        report_fatal_error("data symbols must live in a data section: " +
                           WS.getName());

      // For each data symbol, export it in the symtab as a reference to the
      // corresponding Wasm data segment.
      wasm::WasmDataReference Ref = wasm::WasmDataReference{
          DataSection.getSegmentIndex(),
          static_cast<uint32_t>(Layout.getSymbolOffset(WS)),
          static_cast<uint32_t>(Size)};
      DataLocations[&WS] = Ref;
      LLVM_DEBUG(dbgs() << "  -> segment index: " << Ref.Segment << "\n");

    } else if (WS.isGlobal()) {
      // A "true" Wasm global (currently just __stack_pointer)
      if (WS.isDefined())
        report_fatal_error("don't yet support defined globals");

      // An import; the index was assigned above
      LLVM_DEBUG(dbgs() << "  -> global index: "
                        << WasmIndices.find(&WS)->second << "\n");

    } else if (WS.isEvent()) {
      // C++ exception symbol (__cpp_exception)
      unsigned Index;
      if (WS.isDefined()) {
        Index = NumEventImports + Events.size();
        wasm::WasmEventType Event;
        Event.SigIndex = getEventType(WS);
        Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION;
        assert(WasmIndices.count(&WS) == 0);
        WasmIndices[&WS] = Index;
        Events.push_back(Event);
      } else {
        // An import; the index was assigned above.
        assert(WasmIndices.count(&WS) > 0);
      }
      LLVM_DEBUG(dbgs() << "  -> event index: " << WasmIndices.find(&WS)->second
                        << "\n");

    } else {
      assert(WS.isSection());
    }
  }

  // Populate WasmIndices and DataLocations for aliased symbols.  We need to
  // process these in a separate pass because we need to have processed the
  // target of the alias before the alias itself and the symbols are not
  // necessarily ordered in this way.
  for (const MCSymbol &S : Asm.symbols()) {
    if (!S.isVariable())
      continue;

    assert(S.isDefined());

    // Find the target symbol of this weak alias and export that index
    const auto &WS = static_cast<const MCSymbolWasm &>(S);
    const MCSymbolWasm *ResolvedSym = resolveSymbol(WS);
    LLVM_DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym
                      << "'\n");

    if (ResolvedSym->isFunction()) {
      assert(WasmIndices.count(ResolvedSym) > 0);
      uint32_t WasmIndex = WasmIndices.find(ResolvedSym)->second;
      assert(WasmIndices.count(&WS) == 0);
      WasmIndices[&WS] = WasmIndex;
      LLVM_DEBUG(dbgs() << "  -> index:" << WasmIndex << "\n");
    } else if (ResolvedSym->isData()) {
      assert(DataLocations.count(ResolvedSym) > 0);
      const wasm::WasmDataReference &Ref =
          DataLocations.find(ResolvedSym)->second;
      DataLocations[&WS] = Ref;
      LLVM_DEBUG(dbgs() << "  -> index:" << Ref.Segment << "\n");
    } else {
      report_fatal_error("don't yet support global/event aliases");
    }
  }

  // Finally, populate the symbol table itself, in its "natural" order.
  for (const MCSymbol &S : Asm.symbols()) {
    const auto &WS = static_cast<const MCSymbolWasm &>(S);
    if (!isInSymtab(WS)) {
      WS.setIndex(InvalidIndex);
      continue;
    }
    LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n");

    uint32_t Flags = 0;
    if (WS.isWeak())
      Flags |= wasm::WASM_SYMBOL_BINDING_WEAK;
    if (WS.isHidden())
      Flags |= wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
    if (!WS.isExternal() && WS.isDefined())
      Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
    if (WS.isUndefined())
      Flags |= wasm::WASM_SYMBOL_UNDEFINED;
    if (WS.isNoStrip()) {
      Flags |= wasm::WASM_SYMBOL_NO_STRIP;
      if (isEmscripten()) {
        Flags |= wasm::WASM_SYMBOL_EXPORTED;
      }
    }
    if (WS.hasImportName())
      Flags |= wasm::WASM_SYMBOL_EXPLICIT_NAME;
    if (WS.hasExportName())
      Flags |= wasm::WASM_SYMBOL_EXPORTED;

    wasm::WasmSymbolInfo Info;
    Info.Name = WS.getName();
    Info.Kind = WS.getType();
    Info.Flags = Flags;
    if (!WS.isData()) {
      assert(WasmIndices.count(&WS) > 0);
      Info.ElementIndex = WasmIndices.find(&WS)->second;
    } else if (WS.isDefined()) {
      assert(DataLocations.count(&WS) > 0);
      Info.DataRef = DataLocations.find(&WS)->second;
    }
    WS.setIndex(SymbolInfos.size());
    SymbolInfos.emplace_back(Info);
  }

  {
    auto HandleReloc = [&](const WasmRelocationEntry &Rel) {
      // Functions referenced by a relocation need to put in the table.  This is
      // purely to make the object file's provisional values readable, and is
      // ignored by the linker, which re-calculates the relocations itself.
      if (Rel.Type != wasm::R_WASM_TABLE_INDEX_I32 &&
          Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB)
        return;
      assert(Rel.Symbol->isFunction());
      const MCSymbolWasm &WS = *resolveSymbol(*Rel.Symbol);
      uint32_t FunctionIndex = WasmIndices.find(&WS)->second;
      uint32_t TableIndex = TableElems.size() + InitialTableOffset;
      if (TableIndices.try_emplace(&WS, TableIndex).second) {
        LLVM_DEBUG(dbgs() << "  -> adding " << WS.getName()
                          << " to table: " << TableIndex << "\n");
        TableElems.push_back(FunctionIndex);
        registerFunctionType(WS);
      }
    };

    for (const WasmRelocationEntry &RelEntry : CodeRelocations)
      HandleReloc(RelEntry);
    for (const WasmRelocationEntry &RelEntry : DataRelocations)
      HandleReloc(RelEntry);
  }

  // Translate .init_array section contents into start functions.
  for (const MCSection &S : Asm) {
    const auto &WS = static_cast<const MCSectionWasm &>(S);
    if (WS.getSectionName().startswith(".fini_array"))
      report_fatal_error(".fini_array sections are unsupported");
    if (!WS.getSectionName().startswith(".init_array"))
      continue;
    if (WS.getFragmentList().empty())
      continue;

    // init_array is expected to contain a single non-empty data fragment
    if (WS.getFragmentList().size() != 3)
      report_fatal_error("only one .init_array section fragment supported");

    auto IT = WS.begin();
    const MCFragment &EmptyFrag = *IT;
    if (EmptyFrag.getKind() != MCFragment::FT_Data)
      report_fatal_error(".init_array section should be aligned");

    IT = std::next(IT);
    const MCFragment &AlignFrag = *IT;
    if (AlignFrag.getKind() != MCFragment::FT_Align)
      report_fatal_error(".init_array section should be aligned");
    if (cast<MCAlignFragment>(AlignFrag).getAlignment() != (is64Bit() ? 8 : 4))
      report_fatal_error(".init_array section should be aligned for pointers");

    const MCFragment &Frag = *std::next(IT);
    if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
      report_fatal_error("only data supported in .init_array section");

    uint16_t Priority = UINT16_MAX;
    unsigned PrefixLength = strlen(".init_array");
    if (WS.getSectionName().size() > PrefixLength) {
      if (WS.getSectionName()[PrefixLength] != '.')
        report_fatal_error(
            ".init_array section priority should start with '.'");
      if (WS.getSectionName()
              .substr(PrefixLength + 1)
              .getAsInteger(10, Priority))
        report_fatal_error("invalid .init_array section priority");
    }
    const auto &DataFrag = cast<MCDataFragment>(Frag);
    const SmallVectorImpl<char> &Contents = DataFrag.getContents();
    for (const uint8_t *
             P = (const uint8_t *)Contents.data(),
            *End = (const uint8_t *)Contents.data() + Contents.size();
         P != End; ++P) {
      if (*P != 0)
        report_fatal_error("non-symbolic data in .init_array section");
    }
    for (const MCFixup &Fixup : DataFrag.getFixups()) {
      assert(Fixup.getKind() ==
             MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));
      const MCExpr *Expr = Fixup.getValue();
      auto *SymRef = dyn_cast<MCSymbolRefExpr>(Expr);
      if (!SymRef)
        report_fatal_error("fixups in .init_array should be symbol references");
      const auto &TargetSym = cast<const MCSymbolWasm>(SymRef->getSymbol());
      if (TargetSym.getIndex() == InvalidIndex)
        report_fatal_error("symbols in .init_array should exist in symbtab");
      if (!TargetSym.isFunction())
        report_fatal_error("symbols in .init_array should be for functions");
      InitFuncs.push_back(
          std::make_pair(Priority, TargetSym.getIndex()));
    }
  }

  // Write out the Wasm header.
  writeHeader(Asm);

  writeTypeSection(Signatures);
  writeImportSection(Imports, DataSize, TableElems.size());
  writeFunctionSection(Functions);
  // Skip the "table" section; we import the table instead.
  // Skip the "memory" section; we import the memory instead.
  writeEventSection(Events);
  writeExportSection(Exports);
  writeElemSection(TableElems);
  writeDataCountSection();
  writeCodeSection(Asm, Layout, Functions);
  writeDataSection();
  for (auto &CustomSection : CustomSections)
    writeCustomSection(CustomSection, Asm, Layout);
  writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);
  writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations);
  writeRelocSection(DataSectionIndex, "DATA", DataRelocations);
  writeCustomRelocSections();
  if (ProducersSection)
    writeCustomSection(*ProducersSection, Asm, Layout);
  if (TargetFeaturesSection)
    writeCustomSection(*TargetFeaturesSection, Asm, Layout);

  // TODO: Translate the .comment section to the output.
  return W.OS.tell() - StartOffset;
}

std::unique_ptr<MCObjectWriter>
llvm::createWasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> MOTW,
                             raw_pwrite_stream &OS) {
  return std::make_unique<WasmObjectWriter>(std::move(MOTW), OS);
}

redpajama_set_name: RedPajamaGithub


text:
Q: Move focus to next window shortcut not working when having external monitor So I have this weird issue that everytime I connect my Macbook Air M1 to my LG Ultrafine 5k monitor using USB-C, the Move focus to next window-shortcut is not working:

It doesn't work if I use my external keyboard, or the integrated keyboard on the Macbook.
If I pull out the USB-C cable the shortcut works just fine.
Any ideas?

redpajama_set_name: RedPajamaStackExchange


These Plastic Cocktail Shakers are perfect for bars, restaurants, clubs, fraternities, sororities, promotions, and much more. Our Customized Blinking Light-Up Pints can be converted to a shaker for any event. Eight Shaker colors and over two-dozen imprint colors are available.
Our Plastic Shakers are made in the USA of durable acrylic to ensure long use. Your satisfaction is guaranteed when you order custom barware from us.
SK28 8oz Martini Top Shaker 2.49 2.21 2.11 2.01 1.97 1.93 2" 1.625"
SK212 12oz Shaker 2.59 2.41 2.35 2.31 2.23 2.15 3" 3"
SKCT214 14oz Shaker 3.01 2.83 2.75 2.65 2.57 2.47 2.5" 2"
SK216 16oz Shaker 2.73 2.53 2.45 2.39 2.29 2.23 3" 3"
SKPUB216 16oz Pub Shaker 3.01 2.83 2.75 2.65 2.57 2.47 3" 3"
SK220 20oz Shaker 2.97 2.79 2.69 2.63 2.57 2.47 3" 3"
SK224 24oz Shaker 3.37 3.05 2.95 2.79 2.69 2.65 3" 3"
SK232 32oz Shaker 3.47 3.15 3.05 2.97 2.93 2.89 3" 3"
It's easy to get started with your Custom Plastic Shakers – simply call 1-800-233-0828, and then e-mail your camera-ready artwork to graphics@kardwell.com (you can also mail your design). Production time is about three weeks. Rush delivery is available for an additional charge.